master 016f15443f4f cached
155 files
335.0 KB
83.9k tokens
589 symbols
1 requests
Download .txt
Showing preview only (381K chars total). Download the full file or copy to clipboard to get everything.
Repository: ContainerSolutions/mini-mesos
Branch: master
Commit: 016f15443f4f
Files: 155
Total size: 335.0 KB

Directory structure:
gitextract_yszckrba/

├── .editorconfig
├── .gitignore
├── .pullapprove.yml
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── bin/
│   ├── install
│   ├── install-version
│   └── minimesos
├── build.gradle
├── cli/
│   ├── Dockerfile
│   ├── build.gradle
│   └── src/
│       ├── integration-test/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               └── main/
│       │   │                   ├── CommandInitTest.java
│       │   │                   ├── CommandLogsTest.java
│       │   │                   ├── CommandPsTest.java
│       │   │                   ├── CommandTest.java
│       │   │                   ├── CommandUninstallTest.java
│       │   │                   └── CommandUpTest.java
│       │   └── resources/
│       │       ├── app.json
│       │       ├── clusterconfig/
│       │       │   ├── basic.groovy
│       │       │   └── two-agents.groovy
│       │       ├── configFiles/
│       │       │   ├── complete-minimesosFile
│       │       │   ├── invalid-minimesosFile.txt
│       │       │   ├── marathonAppConfig-minimesosFile
│       │       │   └── withMarathon-minimesosFile
│       │       └── logback-test.xml
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── containersol/
│       │               └── minimesos/
│       │                   └── main/
│       │                       ├── Command.java
│       │                       ├── CommandDestroy.java
│       │                       ├── CommandHelp.java
│       │                       ├── CommandInfo.java
│       │                       ├── CommandInit.java
│       │                       ├── CommandInstall.java
│       │                       ├── CommandLogs.java
│       │                       ├── CommandPs.java
│       │                       ├── CommandState.java
│       │                       ├── CommandUninstall.java
│       │                       ├── CommandUp.java
│       │                       ├── CommandVersion.java
│       │                       └── Main.java
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               └── main/
│           │                   ├── CommandInstallTest.java
│           │                   └── MainTest.java
│           └── resources/
│               ├── app.json
│               └── group.json
├── docs/
│   └── index.md
├── gradle/
│   ├── quality.gradle
│   ├── spock.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── minimesos/
│   ├── build.gradle
│   └── src/
│       ├── integration-test/
│       │   └── java/
│       │       └── com.containersol.minimesos/
│       │           └── integrationtest/
│       │               ├── AuthenticationTest.java
│       │               ├── MesosClusterTest.java
│       │               └── container/
│       │                   ├── HelloWorldContainer.java
│       │                   └── MesosExecuteContainer.java
│       ├── main/
│       │   ├── groovy/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               └── config/
│       │   │                   ├── AgentResourcesConfig.groovy
│       │   │                   ├── AppConfig.groovy
│       │   │                   ├── ClusterConfig.groovy
│       │   │                   ├── ConfigParser.groovy
│       │   │                   ├── ConsulConfig.groovy
│       │   │                   ├── ContainerConfig.groovy
│       │   │                   ├── ContainerConfigBlock.groovy
│       │   │                   ├── GroovyBlock.groovy
│       │   │                   ├── GroupConfig.groovy
│       │   │                   ├── MarathonConfig.groovy
│       │   │                   ├── MesosAgentConfig.groovy
│       │   │                   ├── MesosContainerConfig.groovy
│       │   │                   ├── MesosDNSConfig.groovy
│       │   │                   ├── MesosMasterConfig.groovy
│       │   │                   ├── RegistratorConfig.groovy
│       │   │                   ├── ResourceDef.groovy
│       │   │                   ├── ResourceDefRanges.groovy
│       │   │                   ├── ResourceDefScalar.groovy
│       │   │                   └── ZooKeeperConfig.groovy
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               ├── MinimesosException.java
│       │   │               ├── cluster/
│       │   │               │   ├── ClusterProcess.java
│       │   │               │   ├── ClusterRepository.java
│       │   │               │   ├── ClusterUtil.java
│       │   │               │   ├── Consul.java
│       │   │               │   ├── Filter.java
│       │   │               │   ├── Marathon.java
│       │   │               │   ├── MesosAgent.java
│       │   │               │   ├── MesosCluster.java
│       │   │               │   ├── MesosClusterFactory.java
│       │   │               │   ├── MesosContainer.java
│       │   │               │   ├── MesosDns.java
│       │   │               │   ├── MesosMaster.java
│       │   │               │   ├── Registrator.java
│       │   │               │   └── ZooKeeper.java
│       │   │               ├── docker/
│       │   │               │   ├── DockerClientFactory.java
│       │   │               │   └── DockerContainersUtil.java
│       │   │               ├── integrationtest/
│       │   │               │   └── container/
│       │   │               │       ├── AbstractContainer.java
│       │   │               │       └── ContainerName.java
│       │   │               ├── junit/
│       │   │               │   └── MesosClusterTestRule.java
│       │   │               ├── marathon/
│       │   │               │   └── MarathonContainer.java
│       │   │               ├── mesos/
│       │   │               │   ├── ClusterContainers.java
│       │   │               │   ├── ConsulContainer.java
│       │   │               │   ├── MesosAgentContainer.java
│       │   │               │   ├── MesosClusterContainersFactory.java
│       │   │               │   ├── MesosContainerImpl.java
│       │   │               │   ├── MesosDnsContainer.java
│       │   │               │   ├── MesosMasterContainer.java
│       │   │               │   ├── RegistratorContainer.java
│       │   │               │   └── ZooKeeperContainer.java
│       │   │               ├── state/
│       │   │               │   ├── Discovery.java
│       │   │               │   ├── Executor.java
│       │   │               │   ├── Framework.java
│       │   │               │   ├── Port.java
│       │   │               │   ├── Ports.java
│       │   │               │   ├── State.java
│       │   │               │   └── Task.java
│       │   │               └── util/
│       │   │                   ├── CollectionsUtils.java
│       │   │                   ├── Downloader.java
│       │   │                   ├── Environment.java
│       │   │                   ├── EnvironmentBuilder.java
│       │   │                   ├── Predicate.java
│       │   │                   └── ResourceUtil.java
│       │   └── resources/
│       │       ├── logback.xml
│       │       └── marathon/
│       │           ├── elasticsearch.json
│       │           └── mesos-consul.json
│       └── test/
│           ├── groovy/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               └── config/
│           │                   ├── AgentResourcesConfigTest.groovy
│           │                   ├── ConfigParserTest.groovy
│           │                   ├── ConfigWriterTest.groovy
│           │                   └── ResourceDefScalarTest.groovy
│           ├── java/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               ├── ClusterBuilderTest.java
│           │               ├── ParseStateJSONTest.java
│           │               ├── factory/
│           │               │   └── MesosClusterContainersFactoryTest.java
│           │               ├── integrationtest/
│           │               │   └── container/
│           │               │       ├── ContainerNameTest.java
│           │               │       └── MesosAgentTest.java
│           │               ├── jdepend/
│           │               │   └── JDependCyclesTest.java
│           │               ├── mesos/
│           │               │   ├── ClusterContainersTest.java
│           │               │   └── ClusterUtilTest.java
│           │               └── util/
│           │                   ├── CollectionsUtilsTest.java
│           │                   ├── EnvironmentBuilderTest.java
│           │                   └── ResourceUtilTest.java
│           └── resources/
│               ├── configFiles/
│               │   ├── minimesosFile-authenticationTest
│               │   └── minimesosFile-mesosClusterTest
│               └── logback-test.xml
├── opt/
│   ├── apps/
│   │   └── weave-scope.json
│   ├── sonar/
│   │   ├── DockerFile
│   │   ├── certificate.yaml
│   │   ├── setup.md
│   │   ├── sonar-deployment.yaml
│   │   ├── sonar-plugins/
│   │   │   ├── sonar-github-plugin-1.1.jar
│   │   │   ├── sonar-java-plugin-3.7.1.jar
│   │   │   ├── sonar-scm-git-plugin-1.0.jar
│   │   │   └── sonar-scm-svn-plugin-1.2.jar
│   │   ├── sonar-postgres-deployment.yaml
│   │   ├── sonar-postgres-service.yaml
│   │   └── sonar-service.yaml
│   └── vagrant/
│       └── debian/
│           └── jessie64/
│               ├── Vagrantfile
│               └── provision.sh
├── settings.gradle
└── travis.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true

[*.java]
indent_style = space
indent_size = 4


================================================
FILE: .gitignore
================================================
minimesosFile
.minimesos/*
*.class
.gradle/
build/

# Vagrant working files
.vagrant

# Build system
.gradle/
build/

# IDEA files
*.i??
out/
.idea/

# Maven
/target

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# private docker registry images
.registry


================================================
FILE: .pullapprove.yml
================================================
approve_by_comment: true
approve_regex: ^(Approved|LGTM|:\+1:)
author_approval: ignored
reject_regex: ^Rejected
reset_on_push: false
reviewers:
  members:
  - frankscholten
  - mwl
  - sadovnikov
  - philwinder
  - lguminski
  - adam-sandor
  name: default
  required: 1


================================================
FILE: .travis.yml
================================================
language: java

jdk:
  - oraclejdk8

sudo: required

install:
# one liner installation of docker 1.9.1 below did not work (see https://github.com/moul/travis-docker/issues/38).
#  - curl -sLo - http://j.mp/install-travis-docker | sh -xe
# Therefore installing it through a script
  - sudo sh -c 'echo "deb https://apt.dockerproject.org/repo ubuntu-precise main" > /etc/apt/sources.list.d/docker.list'
  - sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
  - sudo apt-get update
  - sudo apt-key update
  - sudo apt-get -qqy install docker-engine=1.9.1-0~precise
# Has to run this script with sudo because custom installation does not allow $USER to use docker and it's not possible to relogin
  - sudo make deps

# Has to run the build script with sudo because custom installation does not allow $USER to use docker and it's not possible to relogin
script: chmod +x travis.sh && sudo ./travis.sh

notifications:
  email: true
   # see details on https://docs.travis-ci.com/user/notifications
  slack:
    secure: RWUEmM8nef6hH9+AmVaBWVxcjUt5hVPdbw02x+iBdTqAxPC2wxq3Ya/vlWDwhyyXdUgMujfWTJxks3A15qHAzPH22/mVsmAoz8Duspj/C3x8dp/7IncnkbX5AI1fEJy+z+D8uL4J6ALM90y8kUm2QKoddOq1+xO65xZyzvXoxFJDZ9eIlSVsDv7q7qqkaHnWH8nW+DqtGFPlhu5K/luaw56gy7lChUX/KvAy+8fzaUFNPKdJTVu+GpdgJZrqKeQS8+gY00k0AaAS6fOHxTeAUmyC6eDTL1FgBueS5auBha321qU84sQTCQSTHxl0J8YSQzzrBEiGn506DMKFjZLQZWmR4DxxGSc8jd4sdbVXBoWEBQvNI8jZoAzagFnNig1NKPtRAXIuip28FJUhsvK3WOs1H/XsnkRxKZ52jRrDg0yYi48HsqIr7af6nSzAkAK5JEL58Yc1nYvALa0vXjVWuyuo8um0sFNvEDRE/eDi5o6iul0I4CPOM0j+6d8ymVuD6oJ8eeGjYSFVk7XgdCBp1Gcl8NHLgiVjnygcT0U07kszDV7q8ab0iAfjMoTJwFTjPGkwFWJnlD5dciliO7ncWORl//A3JOQqRh5kMp/96995Ia9G4pVnEkh6tQI6G84/qMU0blDrOtTWIO6NjDV4UiGAYtaixr8BGKQWji9K+eY=


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.



================================================
FILE: Makefile
================================================
default: build
.PHONY: setup deps test build

setup:
	sudo route delete 172.17.0.0/16; sudo route -n add 172.17.0.0/16 $(shell docker-machine ip ${shell DOCKER_MACHINE_NAME})

deps:
	docker pull containersol/mesos-agent:1.0.0-0.1.0
	docker pull containersol/mesos-master:1.0.0-0.1.0
	docker pull gliderlabs/registrator:v6
	docker pull consul:0.7.1
	docker pull xebia/mesos-dns:0.0.5
	docker pull mesosphere/marathon:v1.3.5
	docker pull jplock/zookeeper:3.4.6
	docker pull containersol/alpine3.3-java8-jre:v1
	docker pull tutum/hello-world:latest

clean:
	./gradlew clean
	-docker rmi containersol/minimesos-cli:latest

build:
	./gradlew build --info --stacktrace

build-no-tests:
	./gradlew build --info --stacktrace -x test

test:
	./gradlew test --info --stacktrace



================================================
FILE: README.md
================================================
# minimesos [![Build Status](https://travis-ci.org/ContainerSolutions/minimesos.svg?branch=master)](https://travis-ci.org/ContainerSolutions/minimesos)

The experimentation and testing tool for Apache Mesos

NOTE: NO LONGER MAINTAINED!

<div>
<img width="175" src="https://github.com/ContainerSolutions/minimesos/raw/master/images/minimesos.png">
<ul>
  <li><strong>Website</strong>: https://www.minimesos.org
  <li><strong>Source</strong>: https://github.com/ContainerSolutions/minimesos
  <li><strong>Mailing List</strong>: <a href="https://groups.google.com/d/forum/minimesos">minimesos@googlegroups.com</a>
  <li><strong>Slack</strong>: <a href="https://minimesos.slack.com">minimesos.slack.com</a>
  <li><strong>Docs</strong>: <a href="https://readthedocs.org/projects/minimesos">readthedocs.org/projects/minimesos</a>
  <li><strong>Twitter</strong>: <a href="https://twitter.com/minimesos">@minimesos</a>
</ul>
<div style="clear: both;"> 

## Videos

#### MesosCon 2016 Denver - minimesos - The Experimentation and Testing tool for Apache Mesos by Frank Scholten [@frank_scholten](https://twitter.com/Frank_Scholten)

[![minimesos - The Experimentation and Testing tool for Apache Mesos by Frank](https://github.com/ContainerSolutions/minimesos/raw/master/images/minimesos-talk.jpg)](https://www.youtube.com/watch?v=J14_H4T0JB0)

#### Introduction to Minimesos by Viktor Sadovnikov [@sadovnikov](https://twitter.com/sadovnikov)

[![Introduction to minimesos by Viktor](https://raw.githubusercontent.com/containersolutions/minimesos/master/docs/images/introduction-to-minimesos-screenshot.jpg)](https://www.youtube.com/watch?v=jVGyz8sCZSU)


================================================
FILE: bin/install
================================================
#!/bin/sh

# This script is meant for quick & easy install via:
# `sudo curl -sSL https://raw.githubusercontent.com/ContainerSolutions/minimesos/master/bin/install | bash`
#
# Uses the latest release, unless a version identifier is specified as a parameter of this script.

{ # Prevent execution if the script is only partially downloaded

command_exists() {
    command -v "$@" > /dev/null 2>&1
}

install_version() {
    curl -sSL $1 | sh -s $2
}

if ! command_exists curl; then
    echo "Please install curl to fetch the minimesos files"
    exit 1
fi

VERSION=$(echo $@ | xargs)

if [ -z "$VERSION" ]; then
    VERSION=$(curl -s https://api.github.com/repos/containersolutions/minimesos/releases/latest | grep "tag_name" | awk '{ print $2 }' | tr -d '",')
    if [ ! "$VERSION" ]; then
	echo "Cannot determine latest release of minimesos. Please check https://github.com/containersolutions/minimesos/releases"
	exit 1
    fi
fi

# invoking versioned installation script
SCRIPT_PATH=https://raw.githubusercontent.com/ContainerSolutions/minimesos/$VERSION
httpcode=$(curl -s -o /dev/null -I -w '%{http_code}' --max-time 10 --retry-delay 2 --retry 3 $SCRIPT_PATH/bin/install-version || echo "404" )
if [ $httpcode -eq 200 ]; then
    install_version $SCRIPT_PATH/bin/install-version $VERSION
else
    echo "Failed to pull installer off github.com (http err: ${httpcode}), please try again."
    exit 1
fi

exit 0
} # Prevent execution if the script is only partially downloaded



================================================
FILE: bin/install-version
================================================
#!/bin/sh

# This script is meant to be invoked with VERSION given as a parameter.
# Installs the given version of minimesos on the box

{ # Prevent execution if the script is only partially downloaded

command_exists() {
    command -v "$@" > /dev/null 2>&1
}

if ! command_exists curl; then
	echo "Please install curl to fetch the minimesos files"
	exit 1
fi

if [ ! "$#" -eq 1 ]; then
	echo "Version is not given as parameter"
	exit 1
fi

INSTALL_LOCATION=$HOME/.minimesos/bin
VERSION=$1
echo "Installing version " $VERSION
mkdir -p $INSTALL_LOCATION
curl -sSL https://raw.githubusercontent.com/ContainerSolutions/minimesos/$VERSION/bin/minimesos > $INSTALL_LOCATION/minimesos
chmod +x $INSTALL_LOCATION/minimesos

if [ -f "/usr/local/bin/minimesos" ]; then
    echo "Found an old version of minimesos, please remove it:" && echo
    echo "rm -f /usr/local/bin/minimesos" && echo
fi

echo "minimesos is installed into ${INSTALL_LOCATION}/minimesos"
echo "Run the following command to add it to your executables path:" && echo
echo "export PATH=\$PATH:$INSTALL_LOCATION"

exit 0

} # Prevent execution if the script is only partially downloaded


================================================
FILE: bin/minimesos
================================================
#!/usr/bin/env bash

set -e

MINIMESOS_TAG="latest"
PARAMS="$@"
MINIMESOS_CLI_IMAGE="containersol/minimesos-cli"

command_exists() {
    command -v "$@" > /dev/null 2>&1
}

DOCKER_VERSION=$(docker version --format "{{.Server.Version}}")
SMALLEST_VERSION=$(printf "%s\n1.11.0\n" $DOCKER_VERSION | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g | head -n 1)

if ! command_exists docker || [ $SMALLEST_VERSION != "1.11.0" ]; then
    echo "Minimesos requires Docker 1.11.0 or higher"
    exit 1
fi

if [ "$DOCKER_HOST" != "" ] && [[ $DOCKER_HOST == tcp* ]]; then
    DOCKER_HOST_IP=$(echo "$DOCKER_HOST" | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+')
elif command_exists docker-machine && [ "$DOCKER_MACHINE_NAME" != "" ]; then
    DOCKER_HOST_IP=$(docker-machine ip ${DOCKER_MACHINE_NAME})
elif [ $(uname) != "Darwin" ]; then
    DOCKER_HOST_IP=$(ip addr show dev docker0 | grep inet | sed -r "s/.*inet\s([0-9\.]+)\/.*/\1/" | head -n 1)
else
    DOCKER_HOST_IP=""
fi

pullImage() {
    if [ "$(docker images $1 | grep $2 2> /dev/null)" = "" ]; then
	echo "Pulling $1:$2"
	docker pull "$1:$2"
    fi
}

if [ "$#" -gt 0 -a "$1" = up ]; then
    pullImage ${MINIMESOS_CLI_IMAGE} ${MINIMESOS_TAG}
fi

if [ $(uname) == "Darwin" ]; then
  MINIMESOS_OS="Mac OS X"
else
  MINIMESOS_OS="Linux"
fi

MINIMESOS_HOST_DIR="$(pwd)"
MINIMESOS_DIR="$(pwd)/.minimesos"
if [ ! -d "${MINIMESOS_DIR}" ]; then
    mkdir -p "${MINIMESOS_DIR}"
    echo "# Created minimesos directory at ${MINIMESOS_DIR}."
fi


DOCKER_CONTAINER=$(
    docker create --rm \
       -v "${MINIMESOS_HOST_DIR}":"${MINIMESOS_HOST_DIR}" \
       -v /var/run/docker.sock:/var/run/docker.sock \
       -v /sys/fs/cgroup:/sys/fs/cgroup \
       -i \
       --env DOCKER_HOST_IP=${DOCKER_HOST_IP} \
       --env MINIMESOS_OS="${MINIMESOS_OS}" \
       --entrypoint java \
       ${MINIMESOS_CLI_IMAGE}:${MINIMESOS_TAG} \
       -Dminimesos.file="/minimesosFile" \
       -Dminimesos.host.dir="${MINIMESOS_HOST_DIR}" \
       -jar /usr/local/share/minimesos/minimesos-cli.jar ${PARAMS} \
)

docker cp ${MINIMESOS_HOST_DIR}/minimesosFile $DOCKER_CONTAINER:/minimesosFile
docker start -a $DOCKER_CONTAINER


================================================
FILE: build.gradle
================================================
buildscript {

    repositories {
        maven {
            url "http://dl.bintray.com/gesellix/gradle-plugins"
        }
        mavenCentral()
        mavenLocal()
        jcenter()
    }

    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:3.0.2'
        classpath "de.gesellix:gradle-debian-plugin:16"
    }
}

plugins {
    id 'idea'
    id "org.sonarqube" version "1.2"
    id 'net.researchgate.release' version '2.3.5'
    id 'com.bmuschko.docker-remote-api' version '3.0.1'
}

subprojects {

    group = "com.containersol.minimesos"
    version = rootProject.version.toString()

    repositories {
        mavenCentral()
        mavenLocal()
    }

    apply plugin: 'java'
    apply plugin: 'com.bmuschko.docker-remote-api'
    apply plugin: 'maven'
    apply plugin: 'jacoco'

    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'

    [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

    compileJava {
        options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
    }

    task showDeps(type: DependencyReportTask) {}

    test {
        testLogging {
            showStandardStreams = true
        }
    }

    jacocoTestReport {
        reports {
            xml.enabled false
            csv.enabled true
        }
    }

    configurations {
        //workaround for build problem using docker4mac (https://github.com/bmuschko/gradle-docker-plugin/issues/235#issuecomment-239982250)
        dockerJava {
            resolutionStrategy {
                force 'de.gesellix:unix-socket-factory:2016-04-06T22-21-19'
            }
        }
    }

    docker {
        url         = 'unix:///var/run/docker.sock'
        certPath    = null
        if (System.getenv("DOCKER_HOST")) {
            url = System.getenv("DOCKER_HOST").replace("tcp", "https")
            if (System.getenv("DOCKER_CERT_PATH")) {
                certPath = new File(System.getenv("DOCKER_CERT_PATH").toString())
            }
        }
    }
}

ext {
    mesosVer    = "1.0.0"
    repository  = 'containersol'
}

idea {
    project {
        languageLevel = '1.8'
        vcs = 'Git'
    }
}

sonarqube {
    properties {
        property "sonar.sourceEncoding", "UTF-8"
        property "sonar.jacoco.reportPath", "${buildDir}/jacoco/test.exec"
    }
}

task checkDockerAuthentication << {
    // command below return 1 when user is not logged in to Docker Hub
    def command = "docker info | grep \"Username:\"; rc=\$?; if [[ \$rc != 0 ]]; then exit 1; fi"
    // executing via bash, so we can make use of its interpreter of the parameters. Otherwise pipes do not work
    exec {
        commandLine "bash", "-c", command
    }
}

task setVersionInBashScript << {
    if (new File(project.rootDir, "bin/minimesos").text.contains('MINIMESOS_TAG="latest"')) {
        // set explicit version in bash script
        ant.replace(file: "bin/minimesos", token: 'MINIMESOS_TAG="latest"', value: "MINIMESOS_TAG=\"${project.version}\"")
        // commit modified files
        exec {
            workingDir "${project.rootDir}"
            commandLine "git", "commit", "-a", "-m", "[Release ${project.version}] pre-tag commit"
        }
        // push update to repository
        exec {
            workingDir "${project.rootDir}"
            commandLine "git", "push"
        }
    }
}

task resetVersionInBashScript << {
    // have to use regular expression because the project version has changed and the previous is not kept
    ant.replaceregexp(file: "bin/minimesos", match: "MINIMESOS_TAG=\".*?\"", replace: "MINIMESOS_TAG=\"latest\"")
}

task releaseMinimesosCliImage << {

    ['dockerHubUsername', 'dockerHubPassword', 'dockerHubEmail'].each {
        assert project.hasProperty(it): 'Undefined "' + it + '" property'
    }

    docker {
        registryCredentials {
            username = project.property('dockerHubUsername')
            password = project.property('dockerHubPassword')
            email = project.property('dockerHubEmail')
        }
    }

    def minimesosCliImage = "containersol/minimesos-cli"

    def command = "docker tag \$(docker images ${minimesosCliImage} | grep 'latest' | awk '{print \$3}') ${minimesosCliImage}:${project.version}"
    // executing via bash, so we can make use of its interpreter of the parameters. Otherwise pipes do not work
    exec {
        commandLine "bash", "-c", command
    }

    println "Pushing ${minimesosCliImage}:${project.version} docker image to Docker Hub..."
    exec {
        commandLine "docker", "push", "${minimesosCliImage}:${project.version}"
    }

    println "Pushing ${minimesosCliImage}:latest docker image to Docker Hub..."
    exec {
        commandLine "docker", "push", "${minimesosCliImage}:latest"
    }
}

task createGitHubRelease << {
    // use GitHub API
    exec {
        commandLine "curl", "-H", "Content-Type: application/json", "-H", "Authorization: token ${githubAuthToken}", "-XPOST", "-d", "{\"tag_name\":\"${project.version}\"}", "https://api.github.com/repos/ContainerSolutions/minimesos/releases"
    }
}

task updateReleaseDocs << {
    // update online documentation
    exec {
        commandLine "curl", "-XPOST", "https://readthedocs.org/build/minimesos"
    }
    // trigger update of minimesos.org
    exec {
        commandLine "curl", "-H", "x-api-key: ${awsMinimesosOrgApiKey}", "https://kilt52ydsk.execute-api.us-east-1.amazonaws.com/prod/RunHugoGit"
    }
}

// fail the build early if user is not logged in to docker
checkUpdateNeeded.dependsOn checkDockerAuthentication
// set explicit version in minimesos bash script
preTagCommit.dependsOn setVersionInBashScript
// project.version changes after execution of updateVersion. Time to tag and to push container
updateVersion.dependsOn releaseMinimesosCliImage, createGitHubRelease
// project.version changes after execution of updateVersion
commitNewVersion.dependsOn resetVersionInBashScript, updateReleaseDocs

// working around https://github.com/researchgate/gradle-release/issues/144
release {
    buildTasks = ['releaseBuild']
}

task releaseBuild {
    dependsOn(
        'minimesos:clean',
        'minimesos:build',
        'cli:build'
    )
}


================================================
FILE: cli/Dockerfile
================================================
FROM debian:jessie-backports
FROM openjdk:8-jre-alpine
MAINTAINER Container Solutions BV <info@container-solutions.com>

RUN apk add --update curl libstdc++&& \
        rm -rf /var/cache/apk/*

RUN curl https://get.docker.com/builds/Linux/x86_64/docker-1.12.0.tgz -o docker-1.12.0.tgz && \
    tar xzf docker-1.12.0.tgz && \
    mv docker/docker /usr/bin/docker && \
    chmod +x /usr/bin/docker

ADD minimesos-cli.jar /usr/local/share/minimesos/minimesos-cli.jar


================================================
FILE: cli/build.gradle
================================================
apply plugin: 'application'

import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerPushImage
import com.bmuschko.gradle.docker.tasks.image.DockerTagImage

dependencies {
    compile 'com.beust:jcommander:1.48'
    compile 'org.slf4j:slf4j-api:1.7.12'

    compile project(':minimesos')

    testCompile 'junit:junit:4.11'
    testCompile "org.mockito:mockito-core:1.+"
    testCompile "guru.nidi:jdepend:2.9.5"
}

mainClassName = "com.containersol.minimesos.main.Main"

ext {
    imageName = repository + '/minimesos-cli'
}

jar {
    baseName = "minimesos-cli"
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    manifest {
        attributes(
                'Main-Class': mainClassName,
                'Implementation-Version': project.version
        )
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}

artifacts {
    archives jar
}

task copyFilesForDocker(type: Copy) {
    dependsOn 'jar'
    from "build/libs/minimesos-cli-${project.version}.jar"
    into 'build/docker'
    rename { String fileName ->
        fileName.replace("-${project.version}", "")
    }
}

task copyDockerfile(type: Copy) {
    dependsOn 'copyFilesForDocker'
    from "Dockerfile"
    into 'build/docker'
}

task buildDockerImage(type: DockerBuildImage, dependsOn: [copyDockerfile], description: 'build Docker image') {
    inputDir = new File("${buildDir}/docker")
    setTag(project.imageName)
}

afterEvaluate { project ->
    for (tag in ['snapshot', 'version']) {
        String uppercasedTag = tag.capitalize()

        task "tagDockerImageWith$uppercasedTag"(type: DockerTagImage, description: 'tag Docker image') {
            setImageId(project.imageName)
            setTag('version' == tag ? project.version : tag)
            setRepository(project.imageName)
            setForce(true)
        }

        task "publishDockerImageWith$uppercasedTag"(type: DockerPushImage, dependsOn: ["tagDockerImageWith$uppercasedTag"],
                description: 'publish Docker image') {
            setImageName(project.imageName)
            setTag('version' == tag ? project.version : tag)
        }
    }
}

sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integration-test/java')
        }
        resources.srcDir file('src/integration-test/resources')
    }
}

configurations {
    integrationTestCompile.extendsFrom mainCompile
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom mainRuntime
    integrationTestRuntime.extendsFrom testRuntime
}

task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
    testLogging {
        showStandardStreams = true
    }
}

integrationTest.dependsOn buildDockerImage

project.build.dependsOn buildDockerImage

assemble.dependsOn jar


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandInitTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.config.ClusterConfig;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class CommandInitTest {

    private CommandInit commandInit;

    @Before
    public void before() {
        commandInit = new CommandInit();
    }

    @Test
    public void testFileContent() throws IOException {
        String fileContent = commandInit.getConfigFileContent();
        assertTrue("agent section is not found", fileContent.contains("agent {"));
        assertTrue("agent resources section is not found", fileContent.contains("resources {"));
        assertTrue("zookeeper section is not found", fileContent.contains("zookeeper {"));
        assertTrue("consul section is not found", fileContent.contains("consul {"));
        assertTrue("registrator section is not found", fileContent.contains("registrator {"));
        assertTrue("mesosdns section is not found", fileContent.contains("mesosdns {"));
    }

    @Test(expected = MinimesosException.class)
    public void testExecute_existingMiniMesosFile() throws IOException {
        String oldHostDir = System.getProperty(MesosCluster.MINIMESOS_HOST_DIR_PROPERTY);
        File dir = File.createTempFile("mimimesos-test", "dir");
        assertTrue("Failed to delete temp file", dir.delete());
        assertTrue("Failed to create temp directory", dir.mkdir());
        System.setProperty(MesosCluster.MINIMESOS_HOST_DIR_PROPERTY, dir.getAbsolutePath());


        File minimesosFile = new File(dir, ClusterConfig.DEFAULT_CONFIG_FILE);
        Files.write(Paths.get(minimesosFile.getAbsolutePath()), "minimesos { }".getBytes());

        try {
            commandInit.execute();
        } finally {
            if (oldHostDir == null) {
                System.getProperties().remove(MesosCluster.MINIMESOS_HOST_DIR_PROPERTY);
            } else {
                System.setProperty(MesosCluster.MINIMESOS_HOST_DIR_PROPERTY, oldHostDir);
            }
            FileUtils.forceDelete(dir);
        }
    }

    @Test
    public void testValidateParameters() {
        assertTrue(commandInit.validateParameters());
    }

    @Test
    public void testName() {
        assertEquals("init", commandInit.getName());
    }

}


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandLogsTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.cluster.MesosClusterFactory;
import com.containersol.minimesos.mesos.MesosAgentContainer;
import com.containersol.minimesos.mesos.MesosMasterContainer;
import com.containersol.minimesos.state.*;
import com.containersol.minimesos.util.Downloader;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;

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 CommandLogsTest {

    private final String slaveId = "de09c926-7be6-47c6-ab9a-6d1a2b32b642-S0";
    private final String taskId = "http-ports-static-assigned-to-31002.0f732069-a1f2-11e7-97e0-0242ac110006";
    private final String workDir = "/var/lib/mesos/agent-3039938407";
    private final String frameworkId = "de09c926-7be6-47c6-ab9a-6d1a2b32b642-0000";
    private final String runId = "fd7f7182-5ee8-47fc-a1c4-6928aeb1f769";
    private final String agentServiceURL = "http://172.17.0.7:5051";

    private final String PATH_FORMAT = "%s/slaves/%s/frameworks/%s/executors/%s/runs/%s";
    private final String executorDirectory = String.format(PATH_FORMAT, workDir, slaveId, frameworkId, taskId, runId);

    private final String STDOUT_URL = "http://172.17.0.7:5051" +
        "/files/download?path=" +
        "%2Fvar%2Flib%2Fmesos" +
        "%2Fagent-3039938407" +
        "%2Fslaves%2Fde09c926-7be6-47c6-ab9a-6d1a2b32b642-S0" +
        "%2Fframeworks%2Fde09c926-7be6-47c6-ab9a-6d1a2b32b642-0000" +
        "%2Fexecutors%2Fhttp-ports-static-assigned-to-31002.0f732069-a1f2-11e7-97e0-0242ac110006" +
        "%2Fruns%2Ffd7f7182-5ee8-47fc-a1c4-6928aeb1f769" +
        "%2Fstdout";

    private final String STDERR_URL = "http://172.17.0.7:5051" +
        "/files/download?path=" +
        "%2Fvar%2Flib%2Fmesos" +
        "%2Fagent-3039938407" +
        "%2Fslaves%2Fde09c926-7be6-47c6-ab9a-6d1a2b32b642-S0" +
        "%2Fframeworks%2Fde09c926-7be6-47c6-ab9a-6d1a2b32b642-0000" +
        "%2Fexecutors%2Fhttp-ports-static-assigned-to-31002.0f732069-a1f2-11e7-97e0-0242ac110006" +
        "%2Fruns%2Ffd7f7182-5ee8-47fc-a1c4-6928aeb1f769" +
        "%2Fstderr";

    private ByteArrayOutputStream outputStream;

    private PrintStream ps;

    private ClusterRepository repository;

    private Downloader downloader;

    private State masterState;

    private State agentState;

    @Before
    public void initTest() throws URISyntaxException {
        outputStream = new ByteArrayOutputStream();
        ps = new PrintStream(outputStream, true);

        masterState = generateMasterState();
        agentState = generateAgentState();

        MesosMasterContainer master = mock(MesosMasterContainer.class);
        when(master.getState()).thenReturn(masterState);

        MesosAgentContainer agent = mock(MesosAgentContainer.class);
        when(agent.getState()).thenReturn(agentState);
        when(agent.getServiceUrl()).thenReturn(new URI(agentServiceURL));

        MesosCluster mesosCluster = mock(MesosCluster.class);
        when(mesosCluster.getMaster()).thenReturn(master);
        when(mesosCluster.getAgents()).thenReturn(Collections.singletonList(agent));

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

        downloader = mock(Downloader.class);
        when(downloader.getFileContentAsString(STDOUT_URL)).thenReturn("stdout file content");
        when(downloader.getFileContentAsString(STDERR_URL)).thenReturn("stderr file content");
    }

    @Test
    public void TestStdout() throws UnsupportedEncodingException, URISyntaxException {
        // Given
        CommandLogs commandLogs = new CommandLogs(ps);
        commandLogs.setRepository(repository);
        commandLogs.setDownloader(downloader);
        commandLogs.taskId = taskId;

        // When
        commandLogs.execute();

        // Then
        String result = outputStream.toString("UTF-8");
        assertEquals(
            "[minimesos] Fetching 'stdout' of task 'http-ports-static-assigned-to-31002.0f732069-a1f2-11e7-97e0-0242ac110006'\n\n" +
            "stdout file content\n",
            result);

    }

    @Test
    public void TestUnexistingTask() throws UnsupportedEncodingException, URISyntaxException {
        // Given
        CommandLogs commandLogs = new CommandLogs(ps);
        commandLogs.setRepository(repository);
        commandLogs.setDownloader(downloader);
        commandLogs.taskId = "doesn't exist";

        // When
        commandLogs.execute();

        // Then
        String result = outputStream.toString("UTF-8");
        assertEquals("Cannot find task: 'doesn't exist'\n", result);

    }

    @Test
    public void TestStderr() throws UnsupportedEncodingException, URISyntaxException {
        // Given
        CommandLogs commandLogs = new CommandLogs(ps);
        commandLogs.setRepository(repository);
        commandLogs.setDownloader(downloader);
        commandLogs.taskId = taskId;
        commandLogs.stderr = true;

        // When
        commandLogs.execute();

        // Then
        String result = outputStream.toString("UTF-8");
        assertEquals(
            "[minimesos] Fetching 'stderr' of task 'http-ports-static-assigned-to-31002.0f732069-a1f2-11e7-97e0-0242ac110006'\n\n" +
                "stderr file content\n",
            result);
    }

    private State generateAgentState() {
        State state = new State();
        state.setId(slaveId);

        Framework marathon = new Framework();
        marathon.setName("marathon");
        marathon.setId(frameworkId);

        Executor executor = new Executor();
        executor.setDirectory(executorDirectory);
        executor.setId(taskId);
        ArrayList<Executor> executors = new ArrayList<>();
        executors.add(executor);
        marathon.setExecutors(executors);

        ArrayList<Framework> frameworks = new ArrayList<>();
        frameworks.add(marathon);
        state.setFrameworks(frameworks);

        return state;
    }

    private State generateMasterState() {
        State state = new State();
        Framework marathon = new Framework();
        marathon.setName("marathon");

        Task task = new Task();
        task.setName("weave-scope");
        task.setState("TASK_RUNNING");
        task.setId(taskId);
        task.setSlaveId(slaveId);
        task.setFrameworkId(frameworkId);
        task.setExecutorId("");

        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);

        marathon.setTasks(tasks);

        ArrayList<Framework> frameworks = new ArrayList<>();
        frameworks.add(marathon);
        state.setFrameworks(frameworks);

        return state;
    }
}


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandPsTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.cluster.ClusterRepository;
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;
import org.junit.Before;
import org.junit.Test;

import java.io.PrintStream;
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 %-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;

    private PrintStream ps;

    @Before
    public void initTest() {
        outputStream = new ByteArrayOutputStream();
        ps = new PrintStream(outputStream, true);
    }

    @Test
    public void execute() throws UnsupportedEncodingException {
        State state = new State();
        Framework marathon = new Framework();
        marathon.setName("marathon");

        Task task = new Task();
        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);

        marathon.setTasks(tasks);

        ArrayList<Framework> frameworks = new ArrayList<>();
        frameworks.add(marathon);
        state.setFrameworks(frameworks);

        MesosMasterContainer master = mock(MesosMasterContainer.class);
        when(master.getState()).thenReturn(state);

        MesosCluster mesosCluster = mock(MesosCluster.class);
        when(mesosCluster.getMaster()).thenReturn(master);

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

        CommandPs commandPs = new CommandPs(ps);
        commandPs.setRepository(repository);

        commandPs.execute();

        String result = outputStream.toString("UTF-8");
        assertEquals(String.format(FORMAT, COLUMNS) + String.format(FORMAT, VALUES), result);
    }

}


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class CommandTest {

    private ByteArrayOutputStream outputStream;

    private PrintStream ps;

    private ClusterRepository repository = new ClusterRepository();

    @Before
    public void initTest() {
        outputStream = new ByteArrayOutputStream();
        ps = new PrintStream(outputStream, true);
    }

    @Test
    public void testUpAndDestroy() {
        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();

        MesosCluster cluster = commandUp.getCluster();

        File minimesosFile = repository.getMinimesosFile();

        assertTrue("Minimesos file at " + minimesosFile + " should exist", minimesosFile.exists());

        assertEquals(7, cluster.getMemberProcesses().size());

        cluster.destroy(new MesosClusterContainersFactory());

        assertFalse("Minimesos file at " + minimesosFile + " should be removed", minimesosFile.exists());
    }

    @Test
    public void testUp_invalidMinimesosFile() throws IOException {
        FileUtils.write(repository.getMinimesosFile(), "invalid", "UTF-8");

        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();
        MesosCluster cluster = commandUp.getCluster();

        String fileContent = FileUtils.readFileToString(repository.getMinimesosFile(), "UTF-8");
        assertEquals("Invalid state file has not been overwritten", cluster.getClusterId(), fileContent);

        cluster.destroy(new MesosClusterContainersFactory());

        File minimesosFile = repository.getMinimesosFile();

        assertFalse("Minimesos file at " + minimesosFile + " should be removed", minimesosFile.exists());
    }

    @Test
    public void testUp_alreadyRunning() {
        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");

        commandUp.execute();
        MesosCluster firstCluster = commandUp.getCluster();

        commandUp.execute();
        MesosCluster secondCluster = commandUp.getCluster();

        assertEquals(firstCluster, secondCluster);

        MesosClusterContainersFactory factory = new MesosClusterContainersFactory();

        firstCluster.destroy(factory);
        secondCluster.destroy(factory);

        File minimesosFile = repository.getMinimesosFile();

        assertFalse("Minimesos file at " + minimesosFile + " should be removed", minimesosFile.exists());
    }

    @Test
    public void testInfo_runningCluster() throws IOException {
        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();

        CommandInfo commandInfo = new CommandInfo(ps);
        commandInfo.execute();

        String result = outputStream.toString("UTF-8");

        assertTrue(result.contains("Minimesos cluster is running"));
        assertTrue(result.contains("Mesos version"));

        commandUp.getCluster().destroy(new MesosClusterContainersFactory());
    }

    @Test
    public void testInfo_notRunning() throws IOException {
        CommandInfo commandInfo = new CommandInfo(ps);
        commandInfo.execute();

        String result = outputStream.toString("UTF-8");
        assertTrue("Expected phrase not found in: " + result, result.contains("Cluster ID is not found"));
    }

    @Test
    public void testState() throws IOException {
        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();
        MesosCluster cluster = commandUp.getCluster();

        CommandState commandState = new CommandState(ps);
        commandState.execute();

        JSONObject state = new JSONObject(outputStream.toString("UTF-8"));

        assertEquals("master@" + cluster.getMaster().getIpAddress() + ":5050", state.getString("leader"));

        cluster.destroy(new MesosClusterContainersFactory());
    }

    @Test
    public void testInstallCommandValidation() {
        CommandInstall install = new CommandInstall();
        assertFalse("Install command requires one of the parameters", install.validateParameters());
    }

    @Test
    public void testInstall() {
        CommandUp commandUp = new CommandUp();
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();

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

        install.execute();

        commandUp.getCluster().destroy(new MesosClusterContainersFactory());
    }

    @Test(expected = MinimesosException.class)
    public void testInstall_alreadyRunning() {
        CommandUp commandUp = new CommandUp();
        commandUp.execute();

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

        install.execute();
        install.execute();

        commandUp.getCluster().destroy(new MesosClusterContainersFactory());
    }

    @Test
    public void testState_notRunning() throws IOException {
        CommandState commandState = new CommandState(ps);
        commandState.execute();

        String result = outputStream.toString("UTF-8");
        assertTrue(result.contains("Minimesos cluster is not running"));
    }

    @Test
    public void testCompleteInitFile() throws UnsupportedEncodingException {
        CommandUp commandUp = new CommandUp(ps);
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.execute();

        String result = outputStream.toString("UTF-8");

        assertTrue("Command up output does not contain expected line", result.contains("Minimesos cluster is running"));
        assertTrue(result.contains("Mesos version"));

        assertTrue(result.contains("MINIMESOS_MARATHON"));

        commandUp.getCluster().destroy(new MesosClusterContainersFactory());
    }

}


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandUninstallTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
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.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;

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;

    private PrintStream ps;
    private Marathon marathon;
    private MesosCluster mesosCluster;
    private ClusterRepository repository;
    private CommandUninstall commandUninstall;

    @Before
    public void initTest() {
        outputStream = new ByteArrayOutputStream();
        ps = new PrintStream(outputStream, true);

        marathon = Mockito.mock(Marathon.class);

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

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

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

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

        // When
        commandUninstall.execute();

        // 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
    public void execute_appDoesNotExist() throws UnsupportedEncodingException {
        Mockito.doThrow(new MinimesosException("App does not exist")).when(marathon).deleteApp("app");

        commandUninstall.execute();

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


================================================
FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandUpTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.io.IOException;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class CommandUpTest {

    private CommandUp commandUp;

    private ArgumentCaptor<ClusterConfig> capturedClusterConfig;

    private MesosCluster mesosCluster;

    @Before
    public void before() {
        MesosClusterContainersFactory mesosClusterFactory = mock(MesosClusterContainersFactory.class);
        mesosCluster = mock(MesosCluster.class);
        when(mesosCluster.getClusterId()).thenReturn("123456");

        capturedClusterConfig = ArgumentCaptor.forClass(ClusterConfig.class);
        when(mesosClusterFactory.createMesosCluster(capturedClusterConfig.capture())).thenReturn(mesosCluster);

        commandUp = new CommandUp();
        commandUp.setMesosClusterFactory(mesosClusterFactory);
    }

    @Test(expected = MinimesosException.class)
    public void testExecute_missingMinimesosFile() throws IOException {
        commandUp.execute();
    }

    @Test(expected = MinimesosException.class)
    public void testExecute_invalidMinimesosFile() throws IOException {
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/invalid-minimesosFile");
        commandUp.execute();
    }

    @Test
    public void testBasicClusterConfig() throws IOException {
        commandUp.setClusterConfigPath("src/integration-test/resources/clusterconfig/basic.groovy");
        commandUp.execute();

        verify(mesosCluster).start();
    }

    @Test
    public void testExecute_mapPortsToHost() {
        commandUp.setClusterConfigPath("src/integration-test/resources/configFiles/complete-minimesosFile");
        commandUp.setMapPortsToHost(true);
        commandUp.execute();

        assertTrue("Map ports to host from configuration is expected to remain", capturedClusterConfig.getValue().isMapPortsToHost());
    }

}


================================================
FILE: cli/src/integration-test/resources/app.json
================================================
{
  "id": "hello",
  "cmd": "echo 'hello'",
  "cpus": 0.1,
  "mem": 16.0,
  "instances": 1
}

================================================
FILE: cli/src/integration-test/resources/clusterconfig/basic.groovy
================================================
package clusterconfig

minimesos {

    mapPortsToHost = true
    timeout = 60
    mesosVersion = "1.0.0"
    clusterName = "minimesos-test"

    master {
    }

    agent {

        resources {
            cpu {
                role = "logstash"
                value = 0.2
            }
            mem {
                role = "logstash"
                value = 512
            }
            disk {
                role = "*"
                value = 5120
            }
        }

        imageName = "containersol/mesos-agent"
        imageTag = "1.0.0-0.1.0"

    }

    zookeeper {
    }

    marathon {
    }

}


================================================
FILE: cli/src/integration-test/resources/clusterconfig/two-agents.groovy
================================================
package clusterconfig

minimesos {
    agent {
        resources {
            cpu {
                role = "*"
                value = 2
            }
            mem {
                role = "*"
                value = 1024
            }
            disk {
                role = "*"
                value = 8192
            }
        }
    }
    agent {
    }
}


================================================
FILE: cli/src/integration-test/resources/configFiles/complete-minimesosFile
================================================
minimesos {
    clusterName = "Change Cluster Name in minimesosFile file"
    mapPortsToHost = false
    loggingLevel = "INFO"
    mapAgentSandboxVolume = false
    mesosVersion = "0.28"
    timeout = 60

    agent {
        imageName = "containersol/mesos-agent"
        imageTag = "1.0.0-0.1.0"
        loggingLevel = "# INHERIT FROM CLUSTER"
        portNumber = 5051

        resources {

            cpu {
                role = "*"
                value = 4
            }

            disk {
                role = "*"
                value = 2000
            }

            mem {
                role = "*"
                value = 512
            }

            ports {
                role = "*"
                value = "[31000-32000]"
            }
        }
    }

    consul {
        imageName = "consul"
        imageTag = "0.7.1"
    }

    marathon {
        imageName = "mesosphere/marathon"
        imageTag = "v1.3.5"
    }

    master {
        aclJson = null
        authenticate = false
        imageName = "containersol/mesos-master"
        imageTag = "1.0.0-0.1.0"
        loggingLevel = "# INHERIT FROM CLUSTER"
    }

    registrator {
        imageName = "gliderlabs/registrator"
        imageTag = "v6"
    }

    mesosdns {
        imageName = "xebia/mesos-dns"
        imageTag = "0.0.5"
    }

    zookeeper {
        imageName = "jplock/zookeeper"
        imageTag = "3.4.6"
    }
}


================================================
FILE: cli/src/integration-test/resources/configFiles/invalid-minimesosFile.txt
================================================
invalid

================================================
FILE: cli/src/integration-test/resources/configFiles/marathonAppConfig-minimesosFile
================================================
minimesos {
    clusterName = "minimesos-test"
    mapPortsToHost = false
    loggingLevel = "INFO"
    mapAgentSandboxVolume = false
    mesosVersion = "0.28"
    timeout = 60

    agent {
        imageName = "containersol/mesos-agent"
        imageTag = "1.0.0-0.1.0"
        portNumber = 5051

        resources {

            cpu {
                role = "*"
                value = 8
            }

            disk {
                role = "*"
                value = 10000
            }

            mem {
                role = "*"
                value = 1024
            }

            ports {
                role = "*"
                value = "[31000-32000]"
            }
        }
    }

    consul {
        imageName = "consul"
        imageTag = "0.7.1"
    }

    marathon {
        imageName = "mesosphere/marathon"
        imageTag = "v1.3.5"

        app {
          marathonJson = "src/test/resources/app.json"
        }

    }

    master {
        imageName = "containersol/mesos-master"
        imageTag = "1.0.0-0.1.0"
    }

    registrator {
        imageName = "gliderlabs/registrator"
        imageTag = "v6"
    }

    mesosdns {
        imageName = "xebia/mesos-dns"
        imageTag = "0.0.5"
    }

    zookeeper {
        imageName = "jplock/zookeeper"
        imageTag = "3.4.6"
    }
}


================================================
FILE: cli/src/integration-test/resources/configFiles/withMarathon-minimesosFile
================================================
minimesos {
    clusterName = "minimesos-test"
    mapPortsToHost = false
    loggingLevel = "INFO"
    mapAgentSandboxVolume = false
    mesosVersion = "0.28"
    timeout = 60

    marathon {
        imageName = "mesosphere/marathon"
        imageTag = "v1.3.5"
    }
}


================================================
FILE: cli/src/integration-test/resources/logback-test.xml
================================================
<configuration debug="false">

	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<target>System.out</target>
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}: %msg%n</pattern>
		</encoder>
	</appender>

	<logger name="com.containersol.minimesos" level="debug"/>

	<root level="warn">
		<appender-ref ref="console" />
	</root>

</configuration>


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/Command.java
================================================
package com.containersol.minimesos.main;

public interface Command {

    /**
     * Validates combination of command parameters
     *
     * @return true if command parameters are valid
     */
    boolean validateParameters();

    /**
     * @return name of the command
     */
    String getName();

    /**
     * Executes the command
     */
    void execute();

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandDestroy.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameters;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Parameters for the 'destroy' command.
 */
@Parameters(separators = "=", commandDescription = "Destroy a minimesos cluster")
public class CommandDestroy implements Command {

    private static final Logger LOGGER = LoggerFactory.getLogger(CommandDestroy.class);

    public static final String CLINAME = "destroy";

    private ClusterRepository repository = new ClusterRepository();

    @Override
    public void execute() {

        MesosClusterContainersFactory clusterFactory = new MesosClusterContainersFactory();

        MesosCluster cluster = repository.loadCluster(clusterFactory);
        if (cluster != null) {
            cluster.destroy(clusterFactory);
            LOGGER.info("Destroyed minimesos cluster with ID " + cluster.getClusterId());
        } else {
            LOGGER.info("Minimesos cluster is not running");
        }
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandHelp.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameters;

/**
 * Help command
 */
@Parameters(separators = "=", commandDescription = "Display help")
public class CommandHelp implements Command {

    public static final String CLINAME = "help";

    @Override
    public void execute() {
        // Usage is being printed from Main
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInfo.java
================================================
package com.containersol.minimesos.main;

import java.io.PrintStream;
import java.net.URI;
import java.util.List;

import com.beust.jcommander.Parameters;
import com.containersol.minimesos.cluster.ClusterProcess;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.ClusterUtil;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.cluster.MesosDns;
import com.containersol.minimesos.docker.DockerContainersUtil;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import com.containersol.minimesos.util.Environment;

/**
 * Info command
 */
@Parameters(separators = "=", commandDescription = "Display cluster information")
public class CommandInfo implements Command {

    public static final String CLINAME = "info";

    private PrintStream output = System.out; //NOSONAR

    private ClusterRepository repository = new ClusterRepository();

    public CommandInfo() { //NOSONAR
    }

    public CommandInfo(PrintStream ps) {
        this.output = ps;
    }

    @Override
    public void execute() {
        String clusterId = repository.readClusterId();
        if (clusterId != null) {
            MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());
            if (cluster != null) {
                output.println("Minimesos cluster is running: " + cluster.getClusterId());
                output.println("Mesos version: " + cluster.getMaster().getState().getVersion());
                printServiceUrls(cluster);

                MesosDns mesosDns = cluster.getMesosDns();
                if (mesosDns != null) {
                    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()));
            }
        } else {
            output.println("Cluster ID is not found in " + repository.getMinimesosFile().getAbsolutePath());
        }
    }

    /**
     * Prints cluster services URLs and IPs
     *
     * @param cluster to examine
     */
    private void printServiceUrls(MesosCluster cluster) {

        // print independent from roles variables
        String masterContainer = cluster.getMaster().getContainerId();
        String gateway = String.format("export %s=%s", MesosCluster.TOKEN_NETWORK_GATEWAY, DockerContainersUtil.getGatewayIpAddress(masterContainer));
        output.println(gateway);

        List<ClusterProcess> uniqueMembers = ClusterUtil.getDistinctRoleProcesses(cluster.getMemberProcesses());
        for (ClusterProcess process : uniqueMembers) {

            URI serviceUrl = process.getServiceUrl();
            if (serviceUrl != null) {
                String service = String.format("export %s%s=%s", MesosCluster.MINIMESOS_TOKEN_PREFIX, process.getRole().toUpperCase(), serviceUrl.toString());
                String serviceIp = String.format("export %s%s_IP=%s", MesosCluster.MINIMESOS_TOKEN_PREFIX, process.getRole().toUpperCase(), serviceUrl.getHost());

                output.println(String.format("%s; %s", service, serviceIp));
            }

        }

        if (Environment.isRunningInDockerOnMac()) {
            output.println("You are running Docker on Mac so use localhost instead of container IPs for Master, Marathon, Zookeepr and Consul");
        }
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInit.java
================================================
package com.containersol.minimesos.main;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;

import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.config.AppConfig;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.config.ConfigParser;
import com.containersol.minimesos.config.ConsulConfig;
import com.containersol.minimesos.config.MarathonConfig;
import com.containersol.minimesos.config.MesosAgentConfig;
import com.containersol.minimesos.config.MesosDNSConfig;
import com.containersol.minimesos.config.MesosMasterConfig;
import com.containersol.minimesos.config.RegistratorConfig;
import com.containersol.minimesos.config.ZooKeeperConfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.lang.String.format;

/**
 * Initializes a default minimesosFile in the directory where minimesos is run
 */
@Parameters(separators = "=", commandDescription = "Initialize a minimesosFile")
public class CommandInit implements Command {

    private static final Logger LOGGER = LoggerFactory.getLogger(CommandInit.class);

    public static final String CLINAME = "init";

    public static final String DEFAULT_HOST_USERID = "1000";

    @Override
    public boolean validateParameters() {
        return true;
    }

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

    @Override
    public void execute() {
        File minimesosFile = new File(MesosCluster.getClusterHostDir(), ClusterConfig.DEFAULT_CONFIG_FILE);

        if (minimesosFile.exists()) {
            throw new MinimesosException("A minimesosFile already exists in this directory");
        }

        String fileContent = getConfigFileContent();

        Path minimesosPath = Paths.get(minimesosFile.getAbsolutePath());
        try {
            Files.write(minimesosPath, fileContent.getBytes());
        } catch (IOException e) {
            throw new MinimesosException(format("Could not initialize minimesosFile: %s", e.getMessage()), e);
        }

        LOGGER.info("Initialized minimesosFile in this directory");

        try {
            UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
            UserPrincipal owner = lookupService.lookupPrincipalByName(DEFAULT_HOST_USERID);
            Files.setOwner(minimesosPath, owner);
        } catch (IOException e) {
            throw new MinimesosException("NOTE: minimesosFile remains owned by root instead of user ID " + DEFAULT_HOST_USERID + ": " + e.getMessage(), e);
        }

    }

    public String getConfigFileContent() {
        ClusterConfig config = new ClusterConfig();
        config.setClusterName("Change Cluster Name in " + ClusterConfig.DEFAULT_CONFIG_FILE + " file");

        config.setMaster(new MesosMasterConfig(ClusterConfig.DEFAULT_MESOS_VERSION));
        config.setZookeeper(new ZooKeeperConfig());
        config.getAgents().add(new MesosAgentConfig(ClusterConfig.DEFAULT_MESOS_VERSION));
        config.setConsul(new ConsulConfig());
        config.setRegistrator(new RegistratorConfig());
        config.setMesosdns(new MesosDNSConfig());

        AppConfig weaveConfig = new AppConfig();
        weaveConfig.setMarathonJson("https://raw.githubusercontent.com/ContainerSolutions/minimesos/master/opt/apps/weave-scope.json");

        MarathonConfig marathonConfig = new MarathonConfig();
        marathonConfig.getApps().add(weaveConfig);
        config.setMarathon(marathonConfig);

        ConfigParser parser = new ConfigParser();
        return parser.toString(config);
    }

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInstall.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
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 static org.apache.commons.lang.StringUtils.*;

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

    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 = "--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 = "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;

    ClusterRepository repository = new ClusterRepository();

    @Override
    public void execute() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());
        if (cluster != null) {
            Marathon marathon = cluster.getMarathon();
            if (marathon == null) {
                throw new MinimesosException("Marathon container is not found in cluster " + cluster.getClusterId());
            }

            String marathonJson;
            try {
                marathonJson = getMarathonJson();
            } catch (IOException e) {
                throw new MinimesosException("Failed to read JSON file from path, URL or stdin", e);
            }

            if (update) {
                marathon.updateApp(marathonJson);
            } 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 isNotBlank(app) || isNotBlank(group) || isNotBlank(marathonFile);
    }

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

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandLogs.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosAgent;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import com.containersol.minimesos.state.Executor;
import com.containersol.minimesos.state.Framework;
import com.containersol.minimesos.state.State;
import com.containersol.minimesos.state.Task;
import com.containersol.minimesos.util.Downloader;
import org.apache.http.client.utils.URIBuilder;

import java.io.PrintStream;
import java.net.URI;
import java.net.URISyntaxException;

import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang.StringUtils.isBlank;

@Parameters(separators = "=", commandDescription = "Fetches the stdout logs of the specified task")
public class CommandLogs implements Command {

    private PrintStream output = System.out; // NOSONAR

    private ClusterRepository repository = new ClusterRepository();

    private Downloader downloader = new Downloader();

    @Parameter(names = "--task", description = "Substring of a task ID", required = true)
    String taskId = null;

    @Parameter(names = "--stderr", description = "Fetch the stderr logs instead of stdout")
    Boolean stderr = false;

    public CommandLogs(PrintStream output) {
        this.output = output;
    }

    public CommandLogs() {
        //NOSONAR
    }

    @Override
    public boolean validateParameters() {
        return isNotBlank(taskId);
    }

    @Override
    public String getName() {
        return "logs";
    }

    @Override
    public void execute() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());
        if (cluster == null) {
            output.println("Minimesos cluster is not running");
            return;
        }

        State masterState = cluster.getMaster().getState();
        Task task = findTask(masterState, taskId);
        if (task == null) {
            output.println(String.format("Cannot find task: '%s'", taskId));
            return;
        }

        MesosAgent agent = findAgent(cluster, task.getSlaveId());
        if (agent == null) {
            output.println(String.format("Cannot find agent: '%s'", task.getSlaveId()));
            return;
        }


        String filename = stderr ? "stderr" : "stdout";
        output.println(String.format("[minimesos] Fetching '%s' of task '%s'\n", filename, task.getId()));
        URI fileUrl = getFileUrl(agent, task, filename);
        String content = downloader.getFileContentAsString(fileUrl.toString());
        output.println(content);
    }

    public void setRepository(ClusterRepository repository) {
        this.repository = repository;
    }

    void setDownloader(Downloader downloader) {
        this.downloader = downloader;
    }

    private Task findTask(State state, String taskId) {
        for (Framework framework : state.getFrameworks()) {
            for (Task task: framework.getTasks()) {
                if (task.getId().contains(taskId)) {
                    return task;
                }
            }
        }
        return null;
    }

    private MesosAgent findAgent(MesosCluster cluster, String slaveId) {
        for (MesosAgent agent : cluster.getAgents()) {
            State agentState = agent.getState();
            if (agentState.getId().equals(slaveId)) {
                return agent;
            }
        }
        return null;
    }

    private URI getFileUrl(MesosAgent agent, Task task, String filename) throws MinimesosException {
        Executor executor = findExecutor(agent, task);
        if (executor == null) {
            throw new MinimesosException(String.format("Cannot find executor: '%s'", taskId));
        }
        String path = executor.getDirectory();
        URIBuilder uriBuilder = new URIBuilder(agent.getServiceUrl())
            .setPath("/files/download")
            .addParameter("path", path + "/" + filename);
        URI sandboxUrl = null;
        try {
            sandboxUrl = uriBuilder.build();
        } catch (URISyntaxException e) {
            throw new MinimesosException(e.getMessage());
        }
        return sandboxUrl;
    }

    private Executor findExecutor(MesosAgent agent, Task task) {
        String executorId = task.getExecutorId();
        if (isBlank(executorId)) { // if executorId is empty, try with the taskId
            executorId = task.getId();
        }
        for (Framework framework : agent.getState().getFrameworks()) {
            if (framework.getId().equals(task.getFrameworkId())) {
                for (Executor executor : framework.getExecutors()) {
                    if (executor.getId().equals(executorId)) {
                        return executor;
                    }
                }
            }
        }
        return null;
    }

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandPs.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameters;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import com.containersol.minimesos.state.Framework;
import com.containersol.minimesos.state.State;
import com.containersol.minimesos.state.Task;

import java.io.PrintStream;

/**
 * Lists tasks on the cluster
 */
@Parameters(separators = "=", commandDescription = "List running tasks")
public class CommandPs implements Command {

    private static final String FORMAT = "%-20s %-20s %-20s %-20s\n";

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

    private ClusterRepository repository = new ClusterRepository();

    private PrintStream output = System.out; // NOSONAR

    public CommandPs(PrintStream output) {
        this.output = output;
    }

    public CommandPs() {
        // NOSONAR
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

    @Override
    public String getName() {
        return "ps";
    }

    @Override
    public void execute() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());

        if (cluster == null) {
            output.println("Minimesos cluster is not running");
            return;
        }

        output.printf(FORMAT, COLUMNS);
        State state = cluster.getMaster().getState();
        for (Framework framework : state.getFrameworks()) {
            for (Task task : framework.getTasks()) {
                output.printf(FORMAT, framework.getName(), task.getName(), task.getState(), task.getDiscovery().getPorts().getPorts().get(0).getNumber());
            }
        }
    }

    public void setRepository(ClusterRepository repository) {
        this.repository = repository;
    }
}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandState.java
================================================
package com.containersol.minimesos.main;

import java.io.PrintStream;

import com.beust.jcommander.Parameters;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;

/**
 * Parameters for the 'state' command
 */
@Parameters(separators = "=", commandDescription = "Display the master's state.json file")
public class CommandState implements Command {

    public static final String CLINAME = "state";

    private PrintStream output = System.out; //NOSONAR

    private ClusterRepository repository = new ClusterRepository();

    public CommandState() { //NOSONAR
    }

    public CommandState(PrintStream ps) {
        this.output = ps;
    }

    @Override
    public void execute() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());
        if (cluster != null) {
            cluster.state(output);
        } else {
            output.println("Minimesos cluster is not running");
        }
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandUninstall.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.Marathon;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;

import java.io.PrintStream;

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

/**
 * Uninstalls a Marathon app or framework
 */
@Parameters(separators = "=", commandDescription = "Uninstall a Marathon app")
public class CommandUninstall implements Command {

    @Parameter(names = "--app", description = "Marathon app to uninstall")
    private String app = null;

    @Parameter(names = "--group", description = "Marathon group to uninstall")
    private String group = null;

    private ClusterRepository repository = new ClusterRepository();

    private PrintStream output = System.out; // NOSONAR

    CommandUninstall(PrintStream output) {
        this.output = output;
    }

    CommandUninstall() {
        // NOSONAR
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

    @Override
    public String getName() {
        return "uninstall";
    }

    @Override
    public void execute() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());

        if (cluster == null) {
            output.println("Minimesos cluster is not running");
            return;
        }

        Marathon marathon = cluster.getMarathon();
        if (marathon == null) {
            throw new MinimesosException("Marathon container is not found in cluster " + cluster.getClusterId());
        }

        if (isNotBlank(app) && isNotBlank(group)) {
            output.println("Please specify --app or --group to uninstall an app or group");
            return;
        }

        if (isNotBlank(app)) {
            try {
                marathon.deleteApp(app);
                output.println("Deleted app '" + app + "'");
            } catch (MinimesosException e) { // NOSONAR
                output.println(e.getMessage());
            }
        } else if (isNotBlank(group)) {
            try {
                marathon.deleteGroup(group);
                output.println("Deleted group '" + group + "'");
            } catch (MinimesosException e) { // NOSONAR
                output.println(e.getMessage());
            }
        } else {
            output.println("Please specify --app or --group to uninstall an app or group");
        }
    }

    public void setRepository(ClusterRepository repository) {
        this.repository = repository;
    }

    void setApp(String app) {
        this.app = app;
    }

    void setGroup(String group) {
        this.group = group;
    }
}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandUp.java
================================================
package com.containersol.minimesos.main;

import java.io.InputStream;
import java.io.PrintStream;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.config.ConfigParser;
import com.containersol.minimesos.config.MesosMasterConfig;
import com.containersol.minimesos.config.ZooKeeperConfig;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;

import org.apache.commons.io.IOUtils;
import org.slf4j.LoggerFactory;

/**
 * Parameters for the 'up' command
 */
@Parameters(separators = "=", commandDescription = "Create a minimesos cluster")
public class CommandUp implements Command {
    private static final String MINIMESOS_CLUSTER_CONFIG = "minimesos.file";

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(CommandUp.class);

    public static final String CLINAME = "up";

    private ClusterRepository repository = new ClusterRepository();

    @Parameter(names = "--mapPortsToHost", description = "Map the Mesos, Marathon UI, Zookeeper and Consul ports to the host level (we recommend to enable this on Mac (e.g. when using docker-machine) and disable on Linux).")
    private Boolean mapPortsToHost = null;

    @Parameter(names = "--clusterConfig", description = "Path to file with cluster configuration. Defaults to minimesosFile")
    private String clusterConfigPath = ClusterConfig.DEFAULT_CONFIG_FILE;

    private MesosCluster startedCluster = null;

    private PrintStream output = System.out; //NOSONAR

    private MesosClusterContainersFactory mesosClusterFactory;

    public CommandUp() {
        mesosClusterFactory = new MesosClusterContainersFactory();
    }

    public CommandUp(PrintStream ps) {
        this();
        this.output = ps;
    }

    public Boolean isMapPortsToHost() {
        return mapPortsToHost;
    }

    public void setMapPortsToHost(Boolean mapPortsToHost) {
        this.mapPortsToHost = mapPortsToHost;
    }

    public String getClusterConfigPath() {
        String sp = System.getProperty(MINIMESOS_CLUSTER_CONFIG);
        if (sp != null) {
            return sp;
        }
        return clusterConfigPath;
    }

    public void setClusterConfigPath(String clusterConfigPath) {
        this.clusterConfigPath = clusterConfigPath;
    }

    @Override
    public void execute() {
        LOGGER.debug("Executing up command");

        MesosCluster cluster = getCluster();
        if (cluster != null) {
            output.println("Cluster " + cluster.getClusterId() + " is already running");
            return;
        }
        ClusterConfig clusterConfig = readClusterConfigFromMinimesosFile();
        updateWithParameters(clusterConfig);

        startedCluster = mesosClusterFactory.createMesosCluster(clusterConfig);
        // save cluster ID first, so it becomes available for 'destroy' even if its part failed to start
        repository.saveClusterFile(startedCluster);

        startedCluster.start();
        startedCluster.waitForState(state -> state != null);

        new CommandInfo(output).execute();
    }

    /**
     * Reads ClusterConfig from minimesosFile.
     *
     * @return configuration of the cluster from the minimesosFile
     * @throws MinimesosException if minimesosFile is not found or malformed
     */
    public ClusterConfig readClusterConfigFromMinimesosFile() {
        InputStream clusterConfigFile = MesosCluster.getInputStream(getClusterConfigPath());
        if (clusterConfigFile != null) {
            ConfigParser configParser = new ConfigParser();
            try {
                return configParser.parse(IOUtils.toString(clusterConfigFile, "UTF-8"));
            } catch (Exception e) {
                String msg = String.format("Failed to load cluster configuration from %s: %s", getClusterConfigPath(), e.getMessage());
                throw new MinimesosException(msg, e);
            }
        }
        throw new MinimesosException("No minimesosFile found in current directory. Please generate one with 'minimesos init'");
    }

    /**
     * Adjust cluster configuration according to CLI parameters
     *
     * @param clusterConfig cluster configuration to update
     */
    public void updateWithParameters(ClusterConfig clusterConfig) {
        if (isMapPortsToHost() != null) {
            clusterConfig.setMapPortsToHost(isMapPortsToHost());
        }

        if (clusterConfig.getZookeeper() == null) {
            clusterConfig.setZookeeper(new ZooKeeperConfig());
        }

        if (clusterConfig.getMaster() == null) {
            clusterConfig.setMaster(new MesosMasterConfig(ClusterConfig.DEFAULT_MESOS_VERSION));
        }
    }

    public MesosCluster getCluster() {
        return (startedCluster != null) ? startedCluster : repository.loadCluster(new MesosClusterContainersFactory());
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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

    public void setMesosClusterFactory(MesosClusterContainersFactory mesosClusterFactory) {
        this.mesosClusterFactory = mesosClusterFactory;
    }

}


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/CommandVersion.java
================================================
package com.containersol.minimesos.main;

import com.beust.jcommander.Parameters;

import java.io.PrintStream;

/**
 * Command for printing the minimesos version
 */
@Parameters(separators = "=", commandDescription = "Display the version of minimesos")
public class CommandVersion implements Command {

    public static final String CLI_NAME = "version";

    private PrintStream output = System.out; //NOSONAR

    public CommandVersion() { // NOSONAR

    }

    public CommandVersion(PrintStream ps) {
        this.output = ps;
    }

    @Override
    public void execute() {
        Package mainPackage = Main.class.getPackage();
        String version = mainPackage.getImplementationVersion();
        output.println(version);
    }

    @Override
    public boolean validateParameters() {
        return true;
    }

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


================================================
FILE: cli/src/main/java/com/containersol/minimesos/main/Main.java
================================================
package com.containersol.minimesos.main;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;

/**
 * Main method for interacting with minimesos.
 */
@Parameters(separators = "=", commandDescription = "Global options")
public class Main {

    private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

    private static final int EXIT_CODE_OK = 0;
    private static final int EXIT_CODE_ERR = 1;

    @Parameter(names = {"--help", "-help", "-?", "-h"}, description = "Show help")
    private boolean help = false;

    @Parameter(names = "--debug", description = "Enable debug logging.")
    private boolean debug = false;

    private PrintStream output = System.out; //NOSONAR

    private final JCommander jc = new JCommander(this);

    private HashMap<String, Command> commands = new HashMap<>();

    private ClusterRepository repository = new ClusterRepository();

    public static void main(String[] args) {
        Main main = new Main();
        main.addCommand(new CommandUp());
        main.addCommand(new CommandDestroy());
        main.addCommand(new CommandHelp());
        main.addCommand(new CommandInstall());
        main.addCommand(new CommandUninstall());
        main.addCommand(new CommandState());
        main.addCommand(new CommandInfo());
        main.addCommand(new CommandInit());
        main.addCommand(new CommandPs());
        main.addCommand(new CommandVersion());
        main.addCommand(new CommandLogs());
        try {
            int rc = main.run(args);
            if (EXIT_CODE_OK != rc) {
                System.exit(rc);
            }
        } catch (MinimesosException mme) {
            if (main.debug) {
                LOGGER.error("An error, which was handled, occurred", mme);
            } else {
                LOGGER.error(mme.getMessage());
            }
            System.exit(EXIT_CODE_ERR);
        }
    }


    public void setOutput(PrintStream output) {
        this.output = output;
    }

    int run(String[] args) {
        initJCommander();

        try {
            parseParams(jc, args);

            if (help) {
                printUsage(null);
                return EXIT_CODE_OK;
            }

            if (debug) {
                initializeDebugLogging();
            }

            if (jc.getParsedCommand() == null) {
                return handleNoCommand();
            }

            if (!commands.containsKey(jc.getParsedCommand())) {
                LOGGER.error("Unknown command: " + jc.getParsedCommand());
                return EXIT_CODE_ERR;
            }

            Command parsedCommand = commands.get(jc.getParsedCommand());
            if (CommandHelp.CLINAME.equals(parsedCommand.getName())) {
                printUsage(null);
            } else {
                if (parsedCommand.validateParameters()) {
                    parsedCommand.execute();
                } else {
                    printUsage(jc.getParsedCommand());
                    return EXIT_CODE_ERR;
                }
            }

            return EXIT_CODE_OK;
        } catch (Exception ex) {
            PrintWriter writer = new PrintWriter(output);

            output.print("Failed to run command '" + jc.getParsedCommand() + "'.");

            if (ex.getMessage() != null) {
                output.print(" " + ex.getMessage() + ".\n");
            } else {
                ex.printStackTrace(writer);
            }

            writer.close();

            LOGGER.debug("Exception while processing", ex);

            return EXIT_CODE_ERR;
        }
    }

    private void initJCommander() {
        jc.setProgramName("minimesos");
        for (Map.Entry<String, Command> entry : commands.entrySet()) {
            jc.addCommand(entry.getKey(), entry.getValue());
        }
    }

    private void parseParams(JCommander jc, String[] args) {
        try {
            jc.parse(args);
        } catch (Exception e) {
            LOGGER.error("Failed to parse parameters. " + e.getMessage() + "\n");
        }
    }

    private static void initializeDebugLogging() {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        ch.qos.logback.classic.Logger rootLogger = (
            loggerContext.getLogger("com.containersol.minimesos")
        );
        rootLogger.setLevel(Level.DEBUG);
        LOGGER.debug("Initialized debug logging");
    }

    private int handleNoCommand() {
        MesosCluster cluster = repository.loadCluster(new MesosClusterContainersFactory());
        if (cluster != null) {
            new CommandInfo().execute();
            return EXIT_CODE_OK;
        } else {
            printUsage(null);
            return EXIT_CODE_ERR;
        }
    }

    private void printUsage(String commandName) {
        StringBuilder builder = new StringBuilder();
        if (commandName != null) {
            jc.usage(commandName, builder);
        } else {
            jc.usage(builder);
        }
        output.println(builder.toString());
    }

    void addCommand(Command command) {
        commands.put(command.getName(), command);
    }

}


================================================
FILE: cli/src/test/java/com/containersol/minimesos/main/CommandInstallTest.java
================================================
package com.containersol.minimesos.main;

import com.containersol.minimesos.cluster.ClusterRepository;
import com.containersol.minimesos.cluster.Marathon;
import com.containersol.minimesos.cluster.MesosCluster;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;

import java.io.FileReader;
import java.io.IOException;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class CommandInstallTest {

    private Marathon marathon;

    private MesosCluster mesosCluster;

    private ClusterRepository repository;

    private CommandInstall command;

    @Before
    public void before() {
        marathon = mock(Marathon.class);

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

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

        command = new CommandInstall();
        command.repository = repository;
    }

    @Test
    public void testInstallMarathonFile() throws IOException {
        // Given
        command.marathonFile = "src/test/resources/app.json";

        // When
        command.execute();

        // Then
        verify(marathon).deployApp(IOUtils.toString(new FileReader(command.marathonFile)));
    }

    @Test
    public void testInstallMarathonApp() throws IOException {
        // Given
        command.app = "src/test/resources/app.json";

        // When
        command.execute();

        // Then
        verify(marathon).deployApp(IOUtils.toString(new FileReader(command.app)));
    }

    @Test
    public void testInstallMarathonGroup() throws IOException {
        // Given
        command.group = "src/test/resources/group.json";

        // When
        command.execute();

        // Then
        verify(marathon).deployGroup(IOUtils.toString(new FileReader(command.group)));
    }

}


================================================
FILE: cli/src/test/java/com/containersol/minimesos/main/MainTest.java
================================================
package com.containersol.minimesos.main;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.PrintStream;

import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

public class MainTest {

    private ByteArrayOutputStream outputStream;
    private Main main;

    private CommandInfo commandInfo;
    private CommandDestroy commandDestroy;
    private CommandState commandState;
    private CommandInstall commandInstall;
    private CommandUp commandUp;
    private CommandLogs commandLogs;

    @Before
    public void before() {

        outputStream = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(outputStream, true);

        commandUp = spy(new CommandUp());
        doNothing().when(commandUp).execute();

        commandDestroy = spy(new CommandDestroy());
        doNothing().when(commandDestroy).execute();

        commandInfo = spy(new CommandInfo(ps));
        doNothing().when(commandInfo).execute();

        commandState = spy(new CommandState(ps));
        doNothing().when(commandState).execute();

        commandInstall = spy(new CommandInstall());
        doNothing().when(commandInstall).execute();

        commandLogs = spy(new CommandLogs());
        doNothing().when(commandLogs).execute();

        main = new Main();
        main.setOutput(ps);
        main.addCommand(commandUp);
        main.addCommand(commandDestroy);
        main.addCommand(commandInfo);
        main.addCommand(commandState);
        main.addCommand(commandInstall);
        main.addCommand(commandLogs);
        main.addCommand(new CommandHelp());

    }

    @Test
    public void testUp() {
        main.run(new String[]{"up"});
        verify(commandUp).execute();
    }

    @Test
    public void testDestroy() {
        main.run(new String[]{"destroy"});
        verify(commandDestroy).execute();
    }

    @Test
    public void testInfo() throws IOException {
        main.run(new String[]{"info"});
        verify(commandInfo).execute();
    }

    @Test
    public void testState() throws IOException {
        main.run(new String[]{"state"});
        verify(commandState).execute();
    }

    @Test
    public void testInstall() throws IOException {
        main.run(new String[]{"install", "--marathonFile", "bla.json"});
        verify(commandInstall).execute();
    }

    @Test
    public void testLogs() throws IOException {
        main.run(new String[]{"logs", "--task", "something"});
        verify(commandLogs).execute();
    }

    @Test
    public void testLogsNoParameter() throws IOException {
        main.run(new String[]{"logs", "--task"});
        String result = outputStream.toString("UTF-8");
        assertTrue(result.contains("Usage: logs [options]"));
    }

    @Test
    public void testUnsupportedCommand() throws IOException {
        main.run(new String[]{"unsupported"});
        String result = outputStream.toString("UTF-8");
        assertUsageText(result);
    }

    @Test
    public void testMinusMinusHelp() throws IOException {
        main.run(new String[]{"--help"});
        String result = outputStream.toString("UTF-8");
        assertUsageText(result);
    }

    @Test
    public void testInstallNoParameters() throws IOException {
        main.run(new String[]{"install"});
        String output = outputStream.toString("UTF-8");
        assertTrue(output.contains("Usage: install [options]"));
    }

    @Test
    public void testHelp() throws IOException {
        main.run(new String[]{"help"});
        String result = outputStream.toString("UTF-8");
        assertUsageText(result);
    }

    @Test
    public void testNonExistingCommand() throws IOException {
        main.run(new String[]{"foo"});
        String result = outputStream.toString("UTF-8");
        assertUsageText(result);
        assertFalse(result.contains("Failed to run command 'null'. null"));
    }

    private static void assertUsageText(String output) {
        assertTrue(output.contains("Usage: minimesos [options] [command] [command options]"));
        assertTrue(output.contains("Options:"));
        assertTrue(output.contains("Commands:"));
        assertTrue(output.contains("Usage: up [options]"));
        assertTrue(output.contains("Usage: install [options]"));
        assertTrue(output.contains("Usage: state [options]"));
    }

}


================================================
FILE: cli/src/test/resources/app.json
================================================
{
  "id": "hello",
  "container": {
    "type": "MESOS",
    "docker": {
      "image": "weaveworks/",
      "network": "HOST"
    }
  },
  "cpus": 0.1,
  "mem": 16.0,
  "instances": 1
}


================================================
FILE: cli/src/test/resources/group.json
================================================
{
  "id": "pingPongGroup",
  "groups": [
    {
      "id": "ping",
      "cmd": "echo 'ping'",
      "cpus": 0.1,
      "mem": 16.0,
      "instances": 1
    }
   ,{
      "id": "pong",
      "cmd": "echo 'pong'",
      "cpus": 0.1,
      "mem": 16.0,
      "instances": 1
   }
  ]
}


================================================
FILE: docs/index.md
================================================
# minimesos introduction

The experimentation and testing tool for Apache Mesos. `minimesos` is a tool created for a quick and easy creation of a Mesos cluster. This is achieved by running Mesos processes in Docker containers. `minimesos` implements simple to remember and discover CLI commands that allow creating and destroying local Mesos cluster in seconds.

If you have used Vagrant and Docker before, the set of the commands will be very familiar to you, if you have not - don't worry! We will walk you through them.

## Resources

 - Website https://minimesos.org/
 - Blog https://minimesos.org/blog
 - Interactive tutorial https://minimesos.org/try


## System Requirements

minimesos runs Docker containers with a configurable version version of Mesos. See the [minimesos-docker](https://github.com/ContainerSolutions/minimesos-docker) repository
with an overview of the images supported by minimesos.

The Docker client in these Mesos images should be able to talk to Docker daemon on your host machine. The Docker daemon is expected to run version 1.11.0 or higher
of Docker or Docker Machine. See Docker [API compatibility](https://docs.docker.com/engine/reference/api/docker_remote_api/) table.



## Installing

```
$ curl -sSL https://minimesos.org/install | sh
```

This installs the minimesos binary into ``${HOME}/.minimesos/bin``

You can add it to your executables search path using following command:
```
$ export PATH=$PATH:$HOME/.minimesos/bin
```

Once the installation has been successful, let's try running ```minimesos --help```
This should print the list of all possible commands and command line arguments.


These are the options you might want to change to configure your cluster.

## Command line interface

```
Usage: minimesos [options] [command] [command options]
  Options:
    --debug
       Enable debug logging.
       Default: false
    --help, -help, -?, -h
       Show help
       Default: false
  Commands:
    help      Display help
      Usage: help [options]

    init      Initialize a minimesosFile
      Usage: init [options]

    install      Install a framework with Marathon
      Usage: install [options]
        Options:
          --marathonFile
             Marathon JSON app install file location. Either this or --stdin
             parameter must be used
          --stdin
             Use JSON from standard import. Allow piping JSON from other
             processes. Either this or --marathonFile parameter must be used
             Default: false
          --update
             Update a running application instead of attempting to deploy a new
             application
             Default: false

    destroy      Destroy a minimesos cluster
      Usage: destroy [options]

    up      Create a minimesos cluster
      Usage: up [options]
        Options:
          --clusterConfig
             Path to file with cluster configuration. Defaults to minimesosFile
             Default: minimesosFile
          --mapPortsToHost
             Map the Mesos and Marathon UI ports on the host level (we
             recommend to enable this on Mac (e.g. when using docker-machine) and disable
             on Linux).
             Default: false
          --num-agents
             Number of agents to start
             Default: -1
          --timeout
             Time to wait for a container to get responsive, in seconds.
             Default: 60

    state      Display state.json file of a master or an agent
      Usage: state [options]
        Options:
          --agent
             Specify an agent to query, otherwise query a master
             Default: <empty string>

    info      Display cluster information
      Usage: info [options]
```

## minimesosFile and ```minimesos init```
minimesos config is stored in `minimesosFile`, the file that is generated with sensible defaults when running ```minimesos init```

Again, you might notice similarity with ```vagrant init``` and Vagrantfile.
Open the minimesosFile and let's look at the list of the blocks.

The configuration file is a list of blocks, logically grouped by curly brackets ```{ }```
Scalar values are simple key-value strings.

| Option name           | type    | Meaning                                                                            |
|-----------------------|---------|------------------------------------------------------------------------------------|
| clusterName           | String  | The name of the Mesos cluster                                                      |
| mapPortsToHost        | Boolean | Whether to map container ports to the host network                                     |
| loggingLevel          | String  | Debug level in the terminal output                                                 |
| mapAgentSandboxVolume | Boolean | Creates a volume mapping to the agent sandbox under ${PWD}/.minimesos/sandbox-.../ |
| mesosVersion          | String  | Mesos version                                                                      |
| timeout               | Integer | Amount of seconds to wait for the cluster to become alive before giving up         |
| agent                 | Block   | Describes a single instance of a mesos agent                                       |
| agent resources       | Block   | Describes resources of the mesos agent                                             |
| agent resources cpu   | Block   | Describes CPU resources                                                            |
| agent resources mem   | Block   | Describes memory resources                                                         |
| agent resources ports | Block   | Describes network ports resources                                                  |

## Consul and registrator

By default, minimesos starts consul and registrator containers giving you ability to configure service discovery.

## Mesos DNS

Mesos DNS registers Mesos processes and frameworks in its DNS server

## Java API

In this snippet we're configuring the Mesos cluster to start 3 agents with different resources.

```
public class MesosClusterTest {

    @ClassRule
    public static MesosClusterTestRule testRule =
        MesosClusterTestRule.fromFile("src/test/resources/configFiles/testMinimesosFile");

    public static MesosCluster cluster = testRule.getMesosCluster();

    @Test
    public void mesosClusterCanBeStarted() throws Exception {
        JSONObject stateInfo = cluster.getStateInfoJSON();
        Assert.assertEquals(3, stateInfo.getInt("activated_slaves"));
        Assert.assertTrue(cluster.getMesosMasterURL().contains(":5050"));
    }
}
```
## TDD for Mesos frameworks

A possible testing scenario could be:

 1. In the test setup launch the Mesos cluster container
 2. Call the scheduler directly from your test and point to Zookeeper to detect the master or passing the master URL directly.
 3. The scheduler launches a task on a suitable agent.
 4. Poll the state of the Mesos cluster to verify that you framework is running
 5. The test utilities take care of stopping and removing the Mesos cluster

![minimesos](minimesos.png?raw=true "minimesos")

![Creative Commons Licence](cc-cc.png "Creative Commons Licence") Licenced under CC BY [remember to play](http://remembertoplay.co/) in collaboration with [Container Solutions](http://www.container-solutions.com/)

## Building and running on MAC with Docker Machine

### Install DockerToolbox (including Docker Machine)

Download package from <https://www.docker.com/docker-toolbox> and install it.
Tested with [DockerToolbox-1.9.0d.pkg](https://github.com/docker/toolbox/releases/download/v1.9.0d/DockerToolbox-1.9.0d.pkg)

### Creating VM for minimesos

Create a docker machine, make sure its environment variables are visible to the test, ensure the docker containers' IP addresses are available on the host

```
$ docker-machine create -d virtualbox --virtualbox-memory 8192 --virtualbox-cpu-count 1 --engine-opt dns=8.8.8.8 minimesos
$ eval $(docker-machine env minimesos)
```

When VM is ready you can either *build latest version* of minimesos or *install a released version*

### Building latest version of minimesos

In a terminal window, run the following commands:

```
# changing route is required to let Java process on host to find minimesos in virtual machine.
$ sudo route delete 172.17.0.0/16; sudo route -n add 172.17.0.0/16 $(docker-machine ip ${DOCKER_MACHINE_NAME})
$ ./gradlew clean build --info --stacktrace
```

In Idea, add the ```docker-machine env minimesos``` variables to the Idea junit testing dialog. E.g.

```
DOCKER_TLS_VERIFY=1
DOCKER_HOST=tcp://192.168.99.100:2376
DOCKER_CERT_PATH=/home/user/.docker/machine/machines/minimesos
```

One of the minimesos build results is new docker image. E.g.

```
$ docker images
REPOSITORY                      TAG                     IMAGE ID            CREATED             VIRTUAL SIZE
containersol/minimesos-cli      latest                  cf854cfb1865        2 minutes ago       529.3 MB
```

Running ```./gradlew install``` will make latest version of minimesos script available on the PATH

### Running minimesos from CLI

To create minimesos cluster execute ```minimesos up```. It will create temporary container with minimesos process, which will start other containers and will exit.
When cluster is started ```.minimesos/minimesos.cluster``` file with cluster ID is created in local directory. This cluster is destroyed with ```minimesos destroy```

```
$ minimesos init
Initialized minimesosFile in this directory

$ minimesos up
Minimesos cluster is running: 3878417609
Mesos version: 1.0.0
export MINIMESOS_NETWORK_GATEWAY=172.17.0.1
export MINIMESOS_AGENT=http://172.17.0.5:5051; export MINIMESOS_AGENT_IP=172.17.0.5
export MINIMESOS_ZOOKEEPER=zk://172.17.0.3:2181/mesos; export MINIMESOS_ZOOKEEPER_IP=172.17.0.3
export MINIMESOS_MARATHON=http://172.17.0.6:8080; export MINIMESOS_MARATHON_IP=172.17.0.6
export MINIMESOS_CONSUL=http://172.17.0.7:8500; export MINIMESOS_CONSUL_IP=172.17.0.7
export MINIMESOS_MASTER=http://172.17.0.4:5050; export MINIMESOS_MASTER_IP=172.17.0.4

$ minimesos state | jq ".version"
1.0.0

$ minimesos destroy
Destroyed minimesos cluster 3878417609
```

The `minimesos up` command supports `--mapPortsToHost` flag, that automatically binds Mesos and Marathon ports `5050`, resp. `8080` to the host machine, providing you with easy access to the services. Let the following table explain what the host machine is in different contexts:

| --mapPortsToHost   | Linux                            | OS X                                |
|--------------------|----------------------------------|-------------------------------------|
| disabled           | container IP addresses (default) | n/a                                 |
| enabled            | host computer                    | docker-machine IP address (default) |

Having `--mapPortsToHost` enabled on Linux makes minimesos containers effectively accessible to anyone who has network access to your computer.
We don't recommend this. Not using `--mapPortsToHost` flag on Max OS X on the other hand makes the containers inaccessible, because they run inside another virtual machine. This machine is typically managed by `docker-machine`.
Minimesos tries to choose the appropriate configuration for your system automatically.

An other alternative if you use docker-machine, is to access the reported IP address in browser, it's necessary to add routing of docker IP range to IP address of the docker machine

```
sudo route delete 172.17.0.0/16; sudo route -n add 172.17.0.0/16 $(docker-machine ip ${DOCKER_MACHINE_NAME})
```

### Volume maappings

The table below show the volume mappings, on the host, on Docker machine and in the minimesos container.

| OSX Host        | Docker Machine        | minimesos container           |
| --------------- | --------------------- | ----------------------------- |
| $PWD/.minimesos | $PWD/.minimesos       | /tmp/.minimesos               |
|                 | /var/lib/docker       | /var/lib/docker               |
|                 | /var/run/docker.sock  | /var/run/docker.sock          |
|                 | /usr/local/bin/docker | /usr/local/bin/docker         |
|                 | /sys/fs/cgroup        | /sys/fs/cgroup                |


## Caveats

`minimesos up` command supports `--mesosImageTag` parameter, which can be used to override the version of Mesos to be used.
When running an older version of Mesos, you may encounter [compatibility issues between Mesos 0.22 and Docker v. greater than 1.7](https://issues.apache.org/jira/browse/INFRA-10621).

Since version 0.3.0 minimesos uses 'flat' container structure, which means that all containers (agents, master, zookeeper) as well as all Docker executor tasks are run in the same Docker context - the host machine.
This has following benefits:
  1. Shared repository with the host Docker
  2. Transparency of your test cluster.
  3. Ability to keep track of executor tasks
  4. Easy access to the logs

However, you should account for this when developing a Mesos framework.
By default, Mesos starts Docker containerized executor tasks with the ```--host``` mode.
Libprocess tries to bind on a loopback interface and fails to establish communication with the master node.

To work around this, start the executor using [```--bridge``` mode](https://issues.apache.org/jira/browse/MESOS-1621) and provide LIBPROCESS_IP environment variable with the IP address of the executor container, for example using this:

```
export LIBPROCESS_IP=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)

```

This ensures your executor task will be assigned an interface to allow communication within the cluster.


================================================
FILE: gradle/quality.gradle
================================================
apply plugin: 'findbugs'
apply plugin: 'checkstyle'
apply plugin: 'pmd'

tasks.withType(FindBugs) {
  excludeFilter = file("$rootProject.projectDir/config/findbugs/excludeFilter.xml")
}

checkstyle {
    toolVersion = "6.6"
}

pmd {
    toolVersion = "5.1.3"
    ruleSets = [
            'java-basic',
            'java-braces',
            'java-clone',
            'java-codesize',
	        'java-finalizers'
    ]
}

================================================
FILE: gradle/spock.gradle
================================================
// used for unit tests
apply plugin: 'groovy'

def spockVersion = '1.0-groovy-2.4'
def powermockVersion = "1.6.1"

dependencies {

    testCompile "org.codehaus.groovy:groovy-all:2.4.1"
    testCompile "org.spockframework:spock-core:$spockVersion"

    testCompile 'cglib:cglib-nodep:2.2.2'               // need to mock classes

//    // useful to mock out statics and final classes in Java.
//    testCompile "org.powermock:powermock-module-junit4:$powermockVersion"
//    testCompile "org.powermock:powermock-module-junit4-rule:$powermockVersion"
//    testCompile "org.powermock:powermock-classloading-xstream:$powermockVersion"
//    testCompile "org.powermock:powermock-api-mockito:$powermockVersion"
}

// for spock to live in test java tree
sourceSets {
    test {
        groovy { srcDir 'src/test/java' }
    }
}



================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Thu Apr 21 17:15:12 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip


================================================
FILE: gradle.properties
================================================
org.gradle.jvmargs=-Xmx1024M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
release.useAutomaticVersion = false
version=0.14.0
# faster builds: gradle build -x findBugsM



================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: minimesos/build.gradle
================================================
apply plugin: "groovy"

sourceSets {
    main {
        groovy {
            // this makes the groovy-compiler compile groovy- as well as java-files.
            // Needed, because java is normally compiled before groovy.
            // Since we are using groovy objects from java, we need it the other way round.
            srcDirs = ['src/main/groovy', 'src/main/java']
        }
        java {
            srcDirs = [] // don't compile Java code twice
        }
    }

    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integration-test/java')
        }
        resources.srcDir file('src/integration-test/resources')
    }
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.5'
    compile 'com.github.docker-java:docker-java:3.0.7'
    compile 'junit:junit:4.11'
    compile 'com.jayway.awaitility:awaitility:1.6.3'
    compile 'com.mashape.unirest:unirest-java:1.4.8'
    compile 'org.slf4j:slf4j-api:1.7.12'
    compile 'com.mesosphere:marathon-client:0.3.0'
    compile 'com.google.code.gson:gson-parent:2.8.0'

    compile 'ch.qos.logback:logback-core:1.1.3'
    compile 'ch.qos.logback:logback-classic:1.1.3'

    compile 'com.beust:jcommander:1.48'

    testCompile "org.mockito:mockito-core:1.+"
    // using guru.nidi as maintenanance of the original project is dropped https://github.com/clarkware/jdepend/pull/9
    testCompile "guru.nidi:jdepend:2.9.5"

    integrationTestCompile 'junit:junit:4.11'
    integrationTestCompile 'com.jayway.awaitility:awaitility:1.6.3'
}

compileGroovy {
    options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}

configurations {
    integrationTestCompile.extendsFrom mainCompile
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom mainRuntime
    integrationTestRuntime.extendsFrom testRuntime
}

task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
    testLogging {
        showStandardStreams = true
    }
}

task installMinimesosScript(type: Copy) {
    from "$rootDir/bin/minimesos"
    into "/usr/local/bin"
}

integrationTest.dependsOn project(":cli").buildDockerImage


================================================
FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/AuthenticationTest.java
================================================
package com.containersol.minimesos.integrationtest;

import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.junit.MesosClusterTestRule;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;

public class AuthenticationTest {

    public static final String aclExampleUnknownSyntaxUsedInStateJson = "run_tasks {\n  principals {\n    values: \"foo\"\n    values: \"bar\"\n  }\n  users {\n    values: \"alice\"\n  }\n}\n";

    @ClassRule
    public static final MesosClusterTestRule RULE = MesosClusterTestRule.fromFile("src/test/resources/configFiles/minimesosFile-authenticationTest");

    public static MesosCluster CLUSTER = RULE.getMesosCluster();

    @Test
    public void clusterHasZookeeperUrl() throws UnirestException {
        Assert.assertEquals("zk://" + CLUSTER.getZooKeeper().getIpAddress() + ":2181/mesos", CLUSTER.getMaster().getState().getFlags().get("zk"));
    }

    /**
     * See https://issues.apache.org/jira/browse/MESOS-3792. Because of this bug the  acl values are represented
     * as separate key value pairs.
     */
    @Test
    public void extraEnvironmentVariablesPassedToMesosMaster() throws UnirestException {
        Assert.assertEquals("true", CLUSTER.getMaster().getState().getFlags().get("authenticate"));
        Assert.assertEquals(aclExampleUnknownSyntaxUsedInStateJson, CLUSTER.getMaster().getState().getFlags().get("acls"));
    }

}


================================================
FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/MesosClusterTest.java
================================================
package com.containersol.minimesos.integrationtest;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.cluster.ClusterProcess;
import com.containersol.minimesos.cluster.MesosAgent;
import com.containersol.minimesos.cluster.MesosCluster;
import com.containersol.minimesos.cluster.MesosMaster;
import com.containersol.minimesos.cluster.ZooKeeper;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.config.MesosAgentConfig;
import com.containersol.minimesos.integrationtest.container.HelloWorldContainer;
import com.containersol.minimesos.integrationtest.container.MesosExecuteContainer;
import com.containersol.minimesos.docker.DockerClientFactory;
import com.containersol.minimesos.docker.DockerContainersUtil;
import com.containersol.minimesos.junit.MesosClusterTestRule;
import com.containersol.minimesos.marathon.MarathonContainer;
import com.containersol.minimesos.mesos.MesosAgentContainer;
import com.containersol.minimesos.mesos.MesosClusterContainersFactory;
import com.containersol.minimesos.state.State;
import com.containersol.minimesos.util.Environment;
import com.containersol.minimesos.util.ResourceUtil;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.api.model.Link;
import com.github.dockerjava.core.command.LogContainerResultCallback;
import com.jayway.awaitility.Awaitility;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.json.JSONObject;
import org.junit.*;

import java.io.FileNotFoundException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;

public class MesosClusterTest {

    @ClassRule
    public static final MesosClusterTestRule RULE = MesosClusterTestRule.fromFile("src/test/resources/configFiles/minimesosFile-mesosClusterTest");

    public static final MesosCluster CLUSTER = RULE.getMesosCluster();

    @After
    public void after() {
        DockerContainersUtil.getContainers(false).filterByName(HelloWorldContainer.CONTAINER_NAME_PATTERN).kill().remove();
    }

    @Test(expected = MinimesosException.class)
    public void testLoadCluster_noContainersFound() {
        MesosCluster.loadCluster("nonexistent", new MesosClusterContainersFactory());
    }

    @Test
    public void mesosClusterCanBeStarted() throws Exception {
        MesosMaster master = CLUSTER.getMaster();
        State state = master.getState();

        Assert.assertEquals(3, state.getActivatedAgents());
    }

    @Test
    public void mesosResourcesCorrect() throws Exception {
        JSONObject stateInfo = CLUSTER.getMaster().getStateInfoJSON();
        for (int i = 0; i < 3; i++) {
            Assert.assertEquals((long) 4, stateInfo.getJSONArray("slaves").getJSONObject(0).getJSONObject("resources").getLong("cpus"));
            Assert.assertEquals(512, stateInfo.getJSONArray("slaves").getJSONObject(0).getJSONObject("resources").getInt("mem"));
        }
    }

    @Test
    public void dockerExposeResourcesPorts() throws Exception {
        List<MesosAgent> containers = CLUSTER.getAgents();

        for (MesosAgent container : containers) {
            ArrayList<Integer> ports = ResourceUtil.parsePorts(container.getResources());
            InspectContainerResponse response = DockerClientFactory.build().inspectContainerCmd(container.getContainerId()).exec();
            Map bindings = response.getNetworkSettings().getPorts().getBindings();
            for (Integer port : ports) {
                Assert.assertTrue(bindings.containsKey(new ExposedPort(port)));
            }
        }
    }

    @Test
    public void testHelloWorldContainer() throws UnirestException {
        Assume.assumeFalse("Only test hello world container on Linux", Environment.isRunningInJvmOnMacOsX());
        HelloWorldContainer container = new HelloWorldContainer();
        container.start(60);
        URI url = container.getServiceUrl();
        Assert.assertEquals(200, Unirest.get(url.toString()).asString().getStatus());
    }

    @Test
    public void testMasterLinkedToAgents() throws UnirestException {
        List<MesosAgent> containers = CLUSTER.getAgents();
        for (MesosAgent container : containers) {
            InspectContainerResponse exec = DockerClientFactory.build().inspectContainerCmd(container.getContainerId()).exec();

            List<Link> links = Arrays.asList(exec.getHostConfig().getLinks());

            Assert.assertNotNull(links);
            Assert.assertEquals("link to zookeeper is expected", 1, links.size());
            Assert.assertEquals("minimesos-zookeeper", links.get(0).getAlias());
        }
    }

    @Test(expected = IllegalStateException.class)
    public void testStartingClusterSecondTime() {
        CLUSTER.start(30);
    }

    @Test
    public void testMesosVersionRestored() {
        String clusterId = CLUSTER.getClusterId();
        MesosCluster cluster = MesosCluster.loadCluster(clusterId, new MesosClusterContainersFactory());

        Assert.assertEquals("1.0.0", cluster.getConfiguredMesosVersion());
    }

    @Test
    public void testFindMesosMaster() {
        Assume.assumeFalse("Only test token interpolation on Linux", Environment.isRunningInJvmOnMacOsX());

        String initString = "start ${MINIMESOS_MASTER} ${MINIMESOS_MASTER_IP} end";

        String expected = CLUSTER.getMaster().getServiceUrl().toString();
        String ip = CLUSTER.getMaster().getIpAddress();

        MarathonContainer marathon = (MarathonContainer) CLUSTER.getMarathon();
        String updated = marathon.replaceTokens(initString);
        assertEquals("MINIMESOS_MASTER should be replaced", String.format("start %s %s end", expected, ip), updated);
    }

    private static class LogContainerTestCallback extends LogContainerResultCallback {
        final StringBuffer log = new StringBuffer();

        @Override
        public void onNext(Frame frame) {
            log.append(new String(frame.getPayload()));
            super.onNext(frame);
        }

        @Override
        public String toString() {
            return log.toString();
        }
    }

    @Test
    public void testMesosExecuteContainerSuccess() throws InterruptedException {
        ClusterProcess mesosExecute = new MesosExecuteContainer();

        String containerId = CLUSTER.addAndStartProcess(mesosExecute);

        Awaitility.await("Mesos Execute container did not start responding").atMost(60, TimeUnit.SECONDS).until(() -> {
            LogContainerTestCallback cb1 = new LogContainerTestCallback();
            DockerClientFactory.build().logContainerCmd(mesosExecute.getContainerId()).withContainerId(containerId).withStdOut(true).exec(cb1);
            cb1.awaitCompletion();
            String log = cb1.toString();
            return log.contains("Received status update TASK_FINISHED for task 'test-cmd'");
        });
    }

    @Test
    public void noMarathonTest() throws FileNotFoundException {
        String clusterId = CLUSTER.getClusterId();

        Assert.assertNotNull("Cluster ID must be set", clusterId);

        // this should not throw any exceptions
        CLUSTER.destroy(RULE.getFactory());
    }

    @Test
    public void stopWithNewContainerTest() {
        MesosAgent extraAgent = new MesosAgentContainer(new MesosAgentConfig(ClusterConfig.DEFAULT_MESOS_VERSION));
        ZooKeeper zooKeeper = CLUSTER.getZooKeeper();
        extraAgent.setZooKeeper(zooKeeper);

        String containerId = CLUSTER.addAndStartProcess(extraAgent);
        Assert.assertNotNull("freshly started container is not found", DockerContainersUtil.getContainer(containerId));

        CLUSTER.destroy(RULE.getFactory());
        Assert.assertNull("new container should be stopped too", DockerContainersUtil.getContainer(containerId));
    }

    @Test
    public void testStartTwiceShouldNoOp() {
        MesosMaster master = CLUSTER.getMaster();
        master.start(5);
    }

}


================================================
FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/HelloWorldContainer.java
================================================
package com.containersol.minimesos.integrationtest.container;

import com.containersol.minimesos.config.ContainerConfigBlock;
import com.containersol.minimesos.docker.DockerClientFactory;
import com.github.dockerjava.api.command.CreateContainerCmd;
import com.github.dockerjava.api.model.ExposedPort;

/**
 * A container for testing purposes. A small web server on port 80 returns the message "hello world."
 */
public class HelloWorldContainer extends AbstractContainer {
    public static final String SERVICE_NAME = "hello-world-service";
    public static final int SERVICE_PORT = 80;
    public static final String HELLO_WORLD_IMAGE = "tutum/hello-world";
    public static final String CONTAINER_NAME_PATTERN = "^helloworld-[0-9a-f\\-]*$";

    public HelloWorldContainer() {
        super(new ContainerConfigBlock(HELLO_WORLD_IMAGE, "latest"));
    }

    @Override
    public String getRole() {
        return "helloworld";
    }

    @Override
    protected CreateContainerCmd dockerCommand() {
        ExposedPort exposedPort = ExposedPort.tcp(SERVICE_PORT);
        // port mapping is not used as port 80 is ofthen occupied on host
        return DockerClientFactory.build().createContainerCmd(HELLO_WORLD_IMAGE)
                .withEnv(String.format("SERVICE_%d_NAME=%s", SERVICE_PORT, SERVICE_NAME))
                .withPrivileged(true)
                .withName(getName())
                .withExposedPorts(exposedPort);
    }
}


================================================
FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/MesosExecuteContainer.java
================================================
package com.containersol.minimesos.integrationtest.container;

import com.containersol.minimesos.integrationtest.MesosClusterTest;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.config.ContainerConfigBlock;
import com.containersol.minimesos.config.MesosAgentConfig;
import com.containersol.minimesos.docker.DockerClientFactory;
import com.github.dockerjava.api.command.CreateContainerCmd;

public class MesosExecuteContainer extends AbstractContainer {

    private static final String TASK_CLUSTER_ROLE = "test";

    public MesosExecuteContainer() {
        super(new ContainerConfigBlock(MesosAgentConfig.MESOS_AGENT_IMAGE, ClusterConfig.DEFAULT_MESOS_CONTAINER_TAG));
    }

    @Override
    public String getRole() {
        return TASK_CLUSTER_ROLE;
    }

    @Override
    protected CreateContainerCmd dockerCommand() {
        return DockerClientFactory.build().createContainerCmd(String.format("%s:%s", MesosAgentConfig.MESOS_AGENT_IMAGE, ClusterConfig.DEFAULT_MESOS_CONTAINER_TAG))
            .withName(getName())
            .withEntrypoint(
                "mesos-execute",
                "--master=" + MesosClusterTest.CLUSTER.getMaster().getIpAddress() + ":5050",
                "--command=echo 1",
                "--name=test-cmd",
                "--resources=cpus:0.1;mem:128"
            );
    }
}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/AgentResourcesConfig.groovy
================================================
package com.containersol.minimesos.config

import groovy.util.logging.Slf4j

import java.util.regex.Matcher

@Slf4j
class AgentResourcesConfig extends GroovyBlock {

    static public final ResourceDefScalar DEFAULT_CPU = new ResourceDefScalar("*", 4)
    static public final ResourceDefScalar DEFAULT_MEM = new ResourceDefScalar("*", 1024)
    static public final ResourceDefScalar DEFAULT_DISK = new ResourceDefScalar("*", 2000)
    static public final ResourceDefRanges DEFAULT_PORTS = new ResourceDefRanges("*", "[31000-32000]")

    HashMap<String, ResourceDefScalar> cpus
    HashMap<String, ResourceDefScalar> mems
    HashMap<String, ResourceDefScalar> disks
    HashMap<String, ResourceDefRanges> ports

    public AgentResourcesConfig() {
        this(true)
    }

    private AgentResourcesConfig(boolean defaults) {
        cpus = new HashMap<>()
        mems = new HashMap<>()
        disks = new HashMap<>()
        ports = new HashMap<>()
        if (defaults) {
            setDefaults()
        }
    }

    private void setDefaults() {
        addResource(cpus, DEFAULT_CPU)
        addResource(mems, DEFAULT_MEM)
        addResource(disks, DEFAULT_DISK)
        addResource(ports, DEFAULT_PORTS)
    }

    /**
     * Generates resources object from Mesos string definition
     * @param strResources in format like ports(*):[8081-8082]; cpus(*):1.2
     * @return
     */
    static AgentResourcesConfig fromString(String strResources) {

        String pattern = "(\\w+)\\(([A-Za-z0-9_\\*]+)\\):(\\[?[0-9_\\-\\*., ]+\\]?)"
        AgentResourcesConfig resources = new AgentResourcesConfig(false)

        String[] split = strResources.split(";")
        for (String str : split) {
            Matcher matcher = str.trim() =~ pattern
            if (matcher.matches() && (matcher.groupCount() == 3)) {
                String type = matcher.group(1)
                String role = matcher.group(2)
                String value = matcher.group(3)

                switch (type) {
                    case "ports":
                        resources.ports.put(role, new ResourceDefRanges(role, value))
                        break
                    case "cpus":
                        resources.cpus.put(role, new ResourceDefScalar(role, Double.valueOf(value)))
                        break
                    case "mem":
                        resources.mems.put(role, new ResourceDefScalar(role, Double.valueOf(value)))
                        break
                    case "disk":
                        resources.disks.put(role, new ResourceDefScalar(role, Double.valueOf(value)))
                        break
                }

            }
        }

        return resources
    }

    def cpu(@DelegatesTo(ResourceDef) Closure cl) {
        addResource(cpus, loadResourceDef(cl, ResourceDefScalar.class))
    }

    def mem(@DelegatesTo(ResourceDef) Closure cl) {
        addResource(mems, loadResourceDef(cl, ResourceDefScalar.class))
    }

    def disk(@DelegatesTo(ResourceDef) Closure cl) {
        addResource(disks, loadResourceDef(cl, ResourceDefScalar.class))
    }

    def ports(@DelegatesTo(ResourceDef) Closure cl) {
        addResource(ports, loadResourceDef(cl, ResourceDefRanges.class))
    }

    ResourceDef loadResourceDef(Closure cl, Class<ResourceDef> resourceDefClass) {
        ResourceDef resource = resourceDefClass.newInstance()
        delegateTo(resource, cl)
        return resource
    }

    /**
     *
     * @return formatted string with definition of resources. Example: ports(*):[31000-32000]; cpus(*):0.2; mem(*):256; disk(*):200
     */
    String asMesosString() {

        StringBuilder builder = new StringBuilder()

        for (ResourceDef resourceDef : ports.values()) {
            appendResource(builder, resourceDef, "ports")
        }
        for (ResourceDef resourceDef : cpus.values()) {
            appendResource(builder, resourceDef, "cpus")
        }
        for (ResourceDef resourceDef : mems.values()) {
            appendResource(builder, resourceDef, "mem")
        }
        for (ResourceDef resourceDef : disks.values()) {
            appendResource(builder, resourceDef, "disk")
        }

        return builder.toString()

    }

    static void appendResource(StringBuilder builder, ResourceDef resourceDef, String res) {
        if (builder.length() > 0) {
            builder.append("; ")
        }
        builder.append(res).append("(").append(resourceDef.role).append("):").append(resourceDef.valueAsString());
    }

    static void addResource(HashMap<String, ResourceDef> resources, ResourceDef resource) {
        resources.put(resource.role, resource)
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/AppConfig.groovy
================================================
package com.containersol.minimesos.config

/**
 * Configuration for a Marathon app. Path is relative to the minimesosFile.
 */
class AppConfig {

    private String marathonJson

    void setMarathonJson(String marathonJson) {
        this.marathonJson = marathonJson
    }

    String getMarathonJson() {
        return marathonJson
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ClusterConfig.groovy
================================================
package com.containersol.minimesos.config

import groovy.util.logging.Slf4j
import org.apache.commons.lang.StringUtils

@Slf4j
class ClusterConfig extends GroovyBlock {

    public static final int DEFAULT_TIMEOUT_SECS = 60
    public static final String DEFAULT_MESOS_VERSION = "1.0.0"
    public static final String DEFAULT_MINIMESOS_DOCKER_VERSION = "0.1.0"
    public static final String DEFAULT_MESOS_CONTAINER_TAG = DEFAULT_MESOS_VERSION + "-" + DEFAULT_MINIMESOS_DOCKER_VERSION
    public static final String DEFAULT_CONFIG_FILE = "minimesosFile"
    public static final String DEFAULT_LOGGING_LEVEL = "INFO"

    def call(Closure cl) {
        cl.setDelegate(this)
        cl.setResolveStrategy(Closure.DELEGATE_ONLY)
        cl.call()
    }

    boolean mapPortsToHost = false
    boolean mapAgentSandboxVolume = false

    int timeout = DEFAULT_TIMEOUT_SECS
    String mesosVersion = DEFAULT_MESOS_VERSION
    String clusterName = null
    String loggingLevel = DEFAULT_LOGGING_LEVEL

    MesosMasterConfig master = null
    List<MesosAgentConfig> agents = new ArrayList<>()
    ZooKeeperConfig zookeeper = null
    MarathonConfig marathon = null
    MesosDNSConfig mesosdns = null
    ConsulConfig consul = null
    RegistratorConfig registrator = null

    def master(@DelegatesTo(MesosMasterConfig) Closure cl) {
        if (master != null) {
            throw new RuntimeException("Multiple Masters are not supported in this version yet")
        }
        master = new MesosMasterConfig(mesosVersion)
        delegateTo(master, cl)
    }

    def agent(@DelegatesTo(MesosAgentConfig) Closure cl) {
        def agent = new MesosAgentConfig(mesosVersion)
        delegateTo(agent, cl)
        agents.add(agent)
    }

    def zookeeper(@DelegatesTo(ZooKeeperConfig) Closure cl) {
        if (zookeeper != null) {
            throw new RuntimeException("Multiple Zookeepers are not supported in this version yet")
        }
        zookeeper = new ZooKeeperConfig()
        delegateTo(zookeeper, cl)
    }

    def marathon(@DelegatesTo(MarathonConfig) Closure cl) {
        if (marathon != null) {
            throw new RuntimeException("Cannot have more than 1 marathon")
        }
        marathon = new MarathonConfig()
        delegateTo(marathon, cl)
    }

    def mesosdns(@DelegatesTo(MesosDNSConfig) Closure cl) {
        if (mesosdns != null) {
            throw new RuntimeException("Cannot have more than 1 mesosDNS")
        }
        mesosdns = new MesosDNSConfig()
        delegateTo(mesosdns, cl)
    }

    def consul(@DelegatesTo(ConsulConfig) Closure cl) {
        if (consul != null) {
            throw new RuntimeException("Cannot have more than 1 Consul server")
        }
        consul = new ConsulConfig()
        delegateTo(consul, cl)
    }

    def registrator(@DelegatesTo(RegistratorConfig) Closure cl) {
        if (registrator != null) {
            throw new RuntimeException("Cannot have more than 1 registrator")
        }
        registrator = new RegistratorConfig()
        delegateTo(registrator, cl)
    }

    void setLoggingLevel(String loggingLevel) {
        if (!StringUtils.equalsIgnoreCase(loggingLevel, "WARNING") && !StringUtils.equalsIgnoreCase(loggingLevel, "INFO") && !StringUtils.equalsIgnoreCase(loggingLevel, "ERROR")) {
            throw new RuntimeException("Property 'loggingLevel' can only have the values INFO, WARNING or ERROR. Got '" + loggingLevel + "'")
        }
        this.loggingLevel = loggingLevel.toUpperCase()
    }

    void setMesosVersion(String mesosVersion) {
        if (!MesosContainerConfig.MESOS_VERSIONS.contains(mesosVersion)) {
            throw new RuntimeException("Property 'mesosVersion' supports values: " + StringUtils.join(MesosContainerConfig.MESOS_VERSIONS, ","))
        }
        this.mesosVersion = mesosVersion
    }

    String getLoggingLevel() {
        return loggingLevel
    }
}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ConfigParser.groovy
================================================
package com.containersol.minimesos.config

import groovy.util.logging.Slf4j

import java.text.DecimalFormat
import java.text.DecimalFormatSymbols

/**
 * Parser for the minimesosFile. Turns minimesosFile with Groovy DSL specification into a {@link ClusterConfig} object.
 *
 * The minimesosFile DSL contains two components: blocks, and properties. A block starts and ends with curly braces: {}* and properties are nested inside the block. The main block is minimesos and it contains cluster-wide properties.
 * Other blocks contain properties that only affect the block itself like 'imageName' inside an agent block.
 */
@Slf4j
class ConfigParser {

    public static final String CONFIG_VARIABLE = "minimesos"

    private DecimalFormat format = null;

    private final Map<String, String> propsDictionary = [
            "agents": "agent",
            "cpus"  : "cpu",
            "mems"  : "mem",
            "disks" : "disk",
            "apps"  : "app"
    ]
    private final List<String> ignoredProperties = ["class", "format"]

    private final Map<String, String> comments = [
            "minimesos.marathon.apps": "Add 'app { marathonJson = \"<path or URL to JSON file>\" }' for every task you want to execute",
            "minimesos.marathon.cmd": "BEWARE: this option customize the marathon starting command, changing it can break the cluster"
    ]

    public ClusterConfig parse(String config) {
        Binding binding = new Binding()

        ClusterConfig minimesosDsl = new ClusterConfig()
        binding.setVariable(CONFIG_VARIABLE, minimesosDsl)

        GroovyShell shell = new GroovyShell(binding)
        Script script = shell.parse(config)
        script.run()

        return minimesosDsl
    }

    /**
     * Prints cluster configuration into a string
     *
     * @param config of the cluster to print
     * @return string representation of the cluster configuration
     */
    public String toString(ClusterConfig config) {
        String dslPath = CONFIG_VARIABLE
        StringBuilder buffer = new StringBuilder()
        appendPathDescription(buffer, "", dslPath)
        buffer.append(CONFIG_VARIABLE).append(" {\n")
        printProperties(buffer, "    ", config.properties, dslPath)
        buffer.append("}\n")

        buffer.toString()
    }

    private void printProperties(StringBuilder buffer, String intent, Map properties, String dslPath) {

        List<String> propNames = properties.keySet().sort()
        List<String> complexProps = new ArrayList<>()

        for (String propName : propNames) {
            if (!ignoredProperties.contains(propName)) {

                Object value = properties.get(propName)
                String strValue = formatSimpleValue(value)

                if (strValue != null) {
                    appendPathDescription(buffer, intent, dslPath + "." + propName)
                    String line = String.format("%s%s = %s\n", intent, propName, strValue)
                    buffer.append(line)
                } else {
                    complexProps.add(propName)
                }

            }
        }

        if (complexProps.size() > 0) {
            for (String propName : complexProps) {

                Object value = properties.get(propName)
                String propToPrint = propName
                if (propsDictionary.get(propName) != null) {
                    propToPrint = propsDictionary.get(propName)
                }

                if (Collection.class.isAssignableFrom(value.getClass())) {

                    Collection values = (Collection) value
                    printCollection(buffer, intent, propToPrint, values, dslPath + "." + propName)

                } else if (Map.class.isAssignableFrom(value.getClass())) {

                    Map values = (Map) value
                    printCollection(buffer, intent, propToPrint, values.values(), dslPath + "." + propName)

                } else {
                    buffer.append("\n").append(intent).append(propToPrint).append(" {\n")
                    printProperties(buffer, intent + "    ", value.properties, dslPath + "." + propName)
                    buffer.append(intent).append("}\n")
                }
            }
        }
    }

    private void appendPathDescription(StringBuilder buffer, String intent, String dslPath) {
        String comment = comments[dslPath]
        if (comment != null) {
            buffer.append(intent).append("// ").append(comment).append("\n")
        }
    }

    private String formatSimpleValue(Object value) {
        String strValue = null

        if (value == null) {
            strValue = "null"
        } else {

            Class clazz = value.getClass()
            if (String.class.isAssignableFrom(clazz)) {
                strValue = "\"" + value + "\""
            } else if (Integer.class.isAssignableFrom(clazz)) {
                strValue = value.toString()
            } else if (Boolean.class.isAssignableFrom(clazz)) {
                strValue = value.toString()
            } else if (Double.class.isAssignableFrom(clazz)) {
                strValue = getFormat().format(value);
            }

        }

        strValue
    }

    private void printCollection(StringBuilder buffer, String intent, String propName, Collection values, String dslPath) {
        buffer.append("\n")
        appendPathDescription(buffer, intent, dslPath)
        for (Object single : values) {
            String strSingle = formatSimpleValue(single)
            if (strSingle != null) {
                String line = String.format("%s%s = %s\n", intent, propName, strSingle)
                buffer.append(line)
            } else {
                buffer.append(intent).append(propName).append(" {\n")
                printProperties(buffer, intent + "    ", single.properties, dslPath)
            }
            buffer.append(intent).append("}\n")
        }
    }

    private DecimalFormat getFormat() {
        if (format == null) {
            // see http://mesos.apache.org/documentation/latest/attributes-resources/
            // make format locale independent
            DecimalFormatSymbols symbols = new DecimalFormatSymbols();
            symbols.setDecimalSeparator('.' as char)
            format = new DecimalFormat("#.##", symbols)
        }
        return format
    }
}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ConsulConfig.groovy
================================================
package com.containersol.minimesos.config;

public class ConsulConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String CONSUL_IMAGE_NAME = "consul"
    public static final String CONSUL_TAG_NAME = "0.7.1"

    public static final int CONSUL_HTTP_PORT = 8500
    public static final int CONSUL_DNS_PORT = 8600

    public ConsulConfig() {
        imageName = CONSUL_IMAGE_NAME
        imageTag = CONSUL_TAG_NAME
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ContainerConfig.groovy
================================================
package com.containersol.minimesos.config

/**
 * Common methods for containers' configuration
 */
interface ContainerConfig {

    String getImageName()

    void setImageName(String imageName)

    String getImageTag()

    void setImageTag(String imageTag)

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ContainerConfigBlock.groovy
================================================
package com.containersol.minimesos.config;

public class ContainerConfigBlock extends GroovyBlock implements ContainerConfig {

    String imageName;
    String imageTag;

    public ContainerConfigBlock() {
    }

    public ContainerConfigBlock(String name, String tag) {
        this.imageName = name
        this.imageTag = tag;
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/GroovyBlock.groovy
================================================
package com.containersol.minimesos.config;

/**
 * Contains a collection of properties for a configuration object.
 */
class GroovyBlock {

    def delegateTo(Object obj, Closure cl) {
        def code = cl.rehydrate(obj, this, this)
        code.resolveStrategy = Closure.DELEGATE_ONLY
        code()
    }

    def methodMissing(String methodName, args) {
        throw new MissingPropertyException("Block '" + methodName + "' not supported")
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/GroupConfig.groovy
================================================
package com.containersol.minimesos.config;

/**
 * Configuration for a Marathon group. Path is relative to the minimesosFile.
 */
class GroupConfig {

    private String marathonJson

    void setMarathonJson(String marathonJson) {
        this.marathonJson = marathonJson
    }

    String getMarathonJson() {
        return marathonJson
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/MarathonConfig.groovy
================================================
package com.containersol.minimesos.config

import com.containersol.minimesos.MinimesosException

class MarathonConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String MARATHON_IMAGE = "mesosphere/marathon"
    public static final String MARATHON_IMAGE_TAG = "v1.3.5"
    public static final int MARATHON_PORT = 8080
    public static final String MARATHON_CMD = "--master zk://minimesos-zookeeper:2181/mesos --zk zk://minimesos-zookeeper:2181/marathon"

    List<AppConfig> apps = new ArrayList<>()
    List<GroupConfig> groups = new ArrayList<>()
    String cmd

    MarathonConfig() {
        imageName = MARATHON_IMAGE
        imageTag = MARATHON_IMAGE_TAG
        cmd = MARATHON_CMD
    }

    def app(@DelegatesTo(AppConfig) Closure cl) {
        def app = new AppConfig()
        delegateTo(app, cl)

        if (app.getMarathonJson() == null) {
            throw new MinimesosException("App config must have a 'marathonJson' property")
        }
        apps.add(app)
    }

    def group(@DelegatesTo(GroupConfig) Closure cl) {
        def group = new GroupConfig()
        delegateTo(group, cl)

        if (group.getMarathonJson() == null) {
            throw new MinimesosException("Group config must have a 'marathonJson' property")
        }
        groups.add(group)
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/MesosAgentConfig.groovy
================================================
package com.containersol.minimesos.config

import groovy.util.logging.Slf4j

@Slf4j
class MesosAgentConfig extends MesosContainerConfig {

    public static final String MESOS_AGENT_IMAGE = "containersol/mesos-agent"
    public static final int DEFAULT_MESOS_AGENT_PORT = 5051
    public static final String DEFAULT_MESOS_ATTRIBUTES = ""

    int portNumber = DEFAULT_MESOS_AGENT_PORT
    String attributes = DEFAULT_MESOS_ATTRIBUTES

    AgentResourcesConfig resources = new AgentResourcesConfig()

    public MesosAgentConfig(String mesosVersion) {
        imageName = MESOS_AGENT_IMAGE
        imageTag = mesosVersion + "-" + MINIMESOS_DOCKER_TAG
    }

    def resources(@DelegatesTo(AgentResourcesConfig) Closure cl) {
        delegateTo(resources, cl)
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/MesosContainerConfig.groovy
================================================
package com.containersol.minimesos.config

abstract class MesosContainerConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String MESOS_LOGGING_LEVEL_INHERIT = "# INHERIT FROM CLUSTER"
    public static final String MINIMESOS_DOCKER_TAG = "0.1.0"

    private String loggingLevel = MESOS_LOGGING_LEVEL_INHERIT

    public static final List<String> MESOS_VERSIONS = [
            "0.25",
            "0.25.0",
            "0.26",
            "0.27",
            "0.28.0",
            "0.28.1",
            "0.28",
            "1.0.0",
    ]

    public String getLoggingLevel() {
        return loggingLevel
    }

    public void setLoggingLevel(String loggingLevel) {
        this.loggingLevel = loggingLevel.toUpperCase()
    }
}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/MesosDNSConfig.groovy
================================================
package com.containersol.minimesos.config;

public class MesosDNSConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String MESOS_DNS_IMAGE_NAME = "xebia/mesos-dns"
    public static final String MESOS_DNS_TAG_NAME = "0.0.5"

    public MesosDNSConfig() {
        imageName = MESOS_DNS_IMAGE_NAME
        imageTag = MESOS_DNS_TAG_NAME
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/MesosMasterConfig.groovy
================================================
package com.containersol.minimesos.config

import groovy.util.logging.Slf4j

@Slf4j
class MesosMasterConfig extends MesosContainerConfig {

    public static final String MESOS_MASTER_IMAGE = "containersol/mesos-master"
    public static final int MESOS_MASTER_PORT = 5050

    public MesosMasterConfig(String mesosVersion) {
        imageName = MESOS_MASTER_IMAGE
        imageTag = mesosVersion + "-" + MINIMESOS_DOCKER_TAG
    }

    boolean authenticate = false
    String aclJson

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/RegistratorConfig.groovy
================================================
package com.containersol.minimesos.config;

public class RegistratorConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String REGISTRATOR_IMAGE_NAME = "gliderlabs/registrator"
    public static final String REGISTRATOR_TAG_NAME = "v6"

    public RegistratorConfig() {
        imageName = REGISTRATOR_IMAGE_NAME
        imageTag = REGISTRATOR_TAG_NAME
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDef.groovy
================================================
package com.containersol.minimesos.config

/**
 * Check http://mesos.apache.org/documentation/latest/attributes-resources/ for possible types of values
 */
abstract class ResourceDef extends GroovyBlock {

    String role

    protected ResourceDef() {
    }

    protected ResourceDef(String role) {
        this.role = role
    }

    abstract public String valueAsString()

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDefRanges.groovy
================================================
package com.containersol.minimesos.config

/**
 * Check http://mesos.apache.org/documentation/latest/attributes-resources/ for possible types of values
 */
class ResourceDefRanges extends ResourceDef {

    String value

    public ResourceDefRanges() {
    }

    public ResourceDefRanges(String role, String value) {
        super(role)
        this.value = value
    }

    @Override
    String valueAsString() {
        return value
    }
}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDefScalar.groovy
================================================
package com.containersol.minimesos.config

import java.text.DecimalFormat
import java.text.DecimalFormatSymbols

/**
 * Check http://mesos.apache.org/documentation/latest/attributes-resources/ for possible types of values
 */
class ResourceDefScalar extends ResourceDef {

    private DecimalFormat format = null;
    private double value

    public ResourceDefScalar() {
    }

    public ResourceDefScalar(String role, double value) {
        super(role)
        this.value = value
    }

    private DecimalFormat getFormat() {
        if (format == null) {
            // see http://mesos.apache.org/documentation/latest/attributes-resources/
            // make format locale independent
            DecimalFormatSymbols symbols = new DecimalFormatSymbols();
            symbols.setDecimalSeparator('.' as char)
            format = new DecimalFormat("#.##", symbols)
        }
        return format
    }

    public void setValue(double value) {
        this.value = value
    }

    /**
     * Without this explicit setter groovy assigns unexpected values, if they are surrounded by ""
     * @param value to get double from
     */
    public void setValue(String value) {
        // correct format is intValue ( "." intValue )?
        if (value.contains(",")) {
            throw new NumberFormatException(value + " is not valid scalar value")
        }
        this.value = getFormat().parse(value).doubleValue()
    }

    public double getValue() {
        value
    }

    @Override
    String valueAsString() {
        return getFormat().format(value);
    }

}


================================================
FILE: minimesos/src/main/groovy/com/containersol/minimesos/config/ZooKeeperConfig.groovy
================================================
package com.containersol.minimesos.config

public class ZooKeeperConfig extends ContainerConfigBlock implements ContainerConfig {

    public static final String DEFAULT_MESOS_ZK_PATH = "/mesos";
    public static final int DEFAULT_ZOOKEEPER_PORT = 2181;

    public static final String MESOS_LOCAL_IMAGE = "jplock/zookeeper"
    public static final String ZOOKEEPER_IMAGE_TAG = "3.4.6"

    public ZooKeeperConfig() {
        imageName = MESOS_LOCAL_IMAGE
        imageTag = ZOOKEEPER_IMAGE_TAG
    }

}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/MinimesosException.java
================================================
package com.containersol.minimesos;

/**
 * Thrown when a minimesos command fails.
 */
public class MinimesosException extends RuntimeException {

    public MinimesosException(String message) {
        super(message);
    }

    public MinimesosException(String message, Throwable cause) {
        super(message, cause);
    }

}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterProcess.java
================================================
package com.containersol.minimesos.cluster;

import java.net.URI;

/**
 * Generic functionality of every cluster member
 */
public interface ClusterProcess {

    MesosCluster getCluster();

    void setCluster(MesosCluster mesosCluster);

    /**
     * @return the IP address of the container
     */
    String getIpAddress();

    /**
     * @return URI the service is available at (or null)
     */
    URI getServiceUrl();

    /**
     * Builds container name following the naming convention
     *
     * @return container name
     */
    String getName();

    /**
     * @return the ID of the container.
     */
    String getContainerId();

    /**
     * Starts the container and waits until is started
     *
     * @param timeout in seconds
     */
    void start(int timeout);

    String getRole();

    /**
     * Removes a container with force
     */
    void remove();

}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterRepository.java
================================================
package com.containersol.minimesos.cluster;

import com.containersol.minimesos.MinimesosException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Manages persistent information about the minimesos cluster
 */
public class ClusterRepository {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClusterRepository.class);

    public static final String MINIMESOS_FILE_PROPERTY = "minimesos.cluster";

    /**
     * Loads representation of the running cluster
     *
     * @return representation of the cluster, which ID is found in the file
     */
    public MesosCluster loadCluster(MesosClusterFactory factory) {
        String clusterId = readClusterId();
        if (clusterId != null) {
            try {
                return MesosCluster.loadCluster(clusterId, factory);
            } catch (MinimesosException e) {
                deleteMinimesosFile();
            }
        }
        return null;
    }

    /**
     * Writes cluster id to file
     *
     * @param cluster cluster to store ID
     */
    public void saveClusterFile(MesosCluster cluster) {
        String clusterId = cluster.getClusterId();
        File dotMinimesosDir = getMinimesosDir();
        try {
            FileUtils.forceMkdir(dotMinimesosDir);
            String clusterIdPath = dotMinimesosDir.getAbsolutePath() + "/" + MINIMESOS_FILE_PROPERTY;
            Files.write(Paths.get(clusterIdPath), clusterId.getBytes());
            LOGGER.debug("Writing cluster ID " + clusterId + " to " + clusterIdPath);
        } catch (IOException ie) {
            LOGGER.error("Could not write .minimesos folder", ie);
            throw new RuntimeException(ie);
        }
    }

    /**
     * Deletes cluster file
     */
    public void deleteClusterFile() {
        deleteMinimesosFile();
    }

    public String readClusterId() {
        try {
            File minimesosFile = getMinimesosFile();
            String clusterId = FileUtils.readFileToString(minimesosFile, "UTF-8");
            LOGGER.debug("Reading cluster ID from " + minimesosFile + ": " + clusterId);
            return clusterId;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * @return file, possibly non-existing, where cluster information is stored
     */
    public File getMinimesosFile() {
        return new File(getMinimesosDir(), MINIMESOS_FILE_PROPERTY);
    }

    /**
     * @return directory, where minimesos stores ID file
     */
    public File getMinimesosDir() {
        File hostDir = MesosCluster.getClusterHostDir();
        File minimesosDir = new File(hostDir, ".minimesos");
        if (!minimesosDir.exists()) {
            if (!minimesosDir.mkdirs()) {
                throw new MinimesosException("Failed to create " + minimesosDir.getAbsolutePath() + " directory");
            }
        }

        return minimesosDir;
    }

    private void deleteMinimesosFile() {
        File minimesosFile = getMinimesosFile();
        LOGGER.debug("Deleting minimesos.cluster file at " + getMinimesosFile());
        if (minimesosFile.exists()) {
            try {
                FileUtils.forceDelete(minimesosFile);
            } catch (IOException e) {
                // ignore
            }
        }
    }
}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterUtil.java
================================================
package com.containersol.minimesos.cluster;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.containersol.minimesos.cluster.Filter.withRole;

/**
 * Helper methods for ClusterArchitecture
 */
public class ClusterUtil {

    /**
     * Disable constructors
     */
    private ClusterUtil() {
    }

    /**
     * Filters given list of processes and returns only those with distinct roles
     *
     * @param processes complete list of processes
     * @return processes with distinct roles
     */
    public static List<ClusterProcess> getDistinctRoleProcesses(List<ClusterProcess> processes) {

        List<ClusterProcess> distinct = new ArrayList<>();
        Map<String, Integer> roles = new HashMap<>();

        // count processes per role
        for (ClusterProcess process : processes) {
            Integer prev = roles.get(process.getRole());
            int count = (prev != null) ? prev : 0;
            roles.put(process.getRole(), count+1 );
        }

        for (Map.Entry<String, Integer> role : roles.entrySet() ) {
            if (role.getValue() == 1) {
                Optional<ClusterProcess> process = processes.stream().filter(withRole(role.getKey())).findFirst();
                distinct.add(process.get());
            }
        }

        return distinct;

    }

}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Consul.java
================================================
package com.containersol.minimesos.cluster;

/**
 * Consul functionality
 */
public interface Consul extends ClusterProcess {
}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Filter.java
================================================
package com.containersol.minimesos.cluster;

import java.util.function.Predicate;

public class Filter {

    private Filter() {
    }

    public static Predicate<ClusterProcess> zooKeeper() {
        return process -> process instanceof ZooKeeper;
    }

    public static Predicate<ClusterProcess> consul() {
        return process -> process instanceof Consul;
    }

    public static Predicate<ClusterProcess> mesosMaster() {
        return process -> process instanceof MesosMaster;
    }

    public static Predicate<ClusterProcess> mesosAgent() {
        return process -> process instanceof MesosAgent;
    }

    public static Predicate<ClusterProcess> marathon() {
        return process -> process instanceof Marathon;
    }

    public static Predicate<ClusterProcess> withRole(String role) {
        return process -> role.equals(process.getRole());
    }

    public static Predicate<ClusterProcess> registrator() { return process -> process instanceof Registrator; }

    public static Predicate<ClusterProcess> mesosDns() {
        return process -> process instanceof MesosDns;
    }
}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Marathon.java
================================================
package com.containersol.minimesos.cluster;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import mesosphere.marathon.client.model.v2.Result;

/**
 * Functionality, which is expected from Marathon
 */
public interface Marathon extends ClusterProcess {

    /**
     * If Marathon configuration requires, installs the applications
     */
    void installMarathonApps();

    /**
     * Deploys a Marathon app by JSON string
     *
     * @param marathonJson JSON string
     */
    void deployApp(String marathonJson);

    /**
     * Updates a Marathon app by JSON string
     *
     * @param marathonJson JSON string
     */
    void updateApp(String marathonJson);

    /**
     * Kill all apps that are currently running.
     */
    void killAllApps();

    void setZooKeeper(ZooKeeper zookeeper);

    /**
     * Delete the given app
     *
     * @param app to be deleted
     */
    Result deleteApp(String app);

    /**
     * Deploy a Marathon application group.
     *
     * @param groupJson JSON string with Marathon application group definition
     */
    void deployGroup(String groupJson);

    /**
     * Deploy a Marathon application group.
     *
     * @param group group name
     */
    Result deleteGroup(String group);
}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosAgent.java
================================================
package com.containersol.minimesos.cluster;

/**
 * Functionality of Mesos Master
 */
public interface MesosAgent extends MesosContainer {
    String getResources();
}


================================================
FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosCluster.java
================================================
package com.containersol.minimesos.cluster;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URI;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.containersol.minimesos.MinimesosException;
import com.containersol.minimesos.config.ClusterConfig;
import com.containersol.minimesos.state.State;
import com.containersol.minimesos.util.Environment;
import com.containersol.minimesos.util.Predicate;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.github.dockerjava.api.exception.InternalServerErrorException;
import com.github.dockerjava.api.exception.NotFoundException;
import com.mashape.unirest.http.exceptions.UnirestException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.jayway.awaitility.Awaitility.*;
import static org.junit.Assert.assertTrue;

/**
 * Mesos cluster with lifecycle methods such as start, install, info, state, stop and destroy.
 */
public class MesosCluster {

    private static final Logger LOGGER = LoggerFactory.getLogger(MesosCluster.class);

    public static final String MINIMESOS_HOST_DIR_PROPERTY = "minimesos.host.dir";
    public static final String MINIMESOS_TOKEN_PREFIX = "MINIMESOS_";

    public static final String TOKEN_NETWORK_GATEWAY = MINIMESOS_TOKEN_PREFIX + "NETWORK_GATEWAY";

    private String clusterId;

    private final ClusterConfig clusterConfig;

    private List<ClusterProcess> memberProcesses = Collections.synchronizedList(new ArrayList<>());

    private ClusterRepository repository = new ClusterRepository();

    private boolean running = false;

    /**
     * Create a new MesosCluster with a specified cluster architecture.
     */
    public MesosCluster(ClusterConfig clusterConfig, List<ClusterProcess> processes) {
        this.memberProcesses = processes;
        this.clusterConfig = clusterConfig;

        clusterId = Integer.toUnsignedString(new SecureRandom().nextInt());
        for (ClusterProcess process : processes) {
            process.setCluster(this);
        }
    }

    /**
     * Recreate a MesosCluster object based on an existing cluster ID.
     *
     * @param clusterId the cluster ID of the cluster that is already running
     */
    public static MesosCluster loadCluster(String clusterId, MesosClusterFactory factory) {
        return new MesosCluster(clusterId, factory);
    }

    /**
     * This constructor is used for deserialization of running cluster
     *
     * @param clusterId ID of the cluster to deserialize
     */
    private MesosCluster(String clusterId, MesosClusterFactory factory) {
        this.clusterId = clusterId;
        this.clusterConfig = new ClusterConfig();

        if (Environment.isRunningInJvmOnMacOsX() || Environment.isRunningInDockerOnMac()) {
            LOGGER.info("Detected Mac Environment X so running with --mapPortsToHost so master and marathon ports are mapped to localhost.");
            setMapPortsToHost(true);
        }

        factory.loadRunningCluster(this);

        if (memberProcesses.isEmpty()) {
            throw new MinimesosException("No containers found for cluster ID " + clusterId);
        }

        ZooKeeper zookeeper = getZooKeeper();
        MesosMaster master = getMaster();

        if (master != null && zookeeper != null) {
            for (MesosAgent mesosAgent : getAgents()) {
                mesosAgent.setZooKeeper(zookeeper);
            }
            if (getMarathon() != null) {
                getMarathon().setZooKeeper(zookeeper);
            }
        }

        running = true;
    }

    /**
     * Starts the Mesos cluster and its containers with 60 second timeout.
     * The method is used by frameworks
     */
    public void start() {
        start(clusterConfig.getTimeout());
    }

    /**
     * Starts the Mesos cluster and its containers with given timeout.
     *
     * @param timeoutSeconds seconds to wait until timeout
     */
    public void start(int timeoutSeconds) {
        if (running) {
            throw new IllegalStateException("Cluster " + clusterId + " is already running");
        }

        if (Environment.isRunningInJvmOnMacOsX() || Environment.isRunningInDockerOnMac()) {
            LOGGER.info("Detected Mac Environment X, running with '--mapPortsToHost' so master and marathon ports are mapped to localhost");
            clusterConfig.setMapPortsToHost(true);
        }

        LOGGER.debug("Cluster " + getClusterId() + " - start");
        this.memberProcesses.forEach((container) -> container.start(timeoutSeconds));
        // wait until the given number of agents are registered
        getMaster().waitFor();

        Marathon marathon = getMarathon();
        if (marathon != null) {
            marathon.installMarathonApps();
        }

        running = true;
    }

    /**
     * Prints the state of the Mesos master or agent
     */
    public void state(PrintStream out) {
        JSONObject stateInfo = getClusterStateInfo();
        if (stateInfo != null) {
            out.println(stateInfo.toString(2));
        } else {
            throw new MinimesosException("Could not retrieve the state from the cluster at " + getMaster().getServiceUrl() + ". Is it running?");
        }
    }

    /**
     * Destroys the Mesos cluster and its containers
     */
    public void destroy(MesosClusterFactory factory) {
        LOGGER.debug("Cluster " + getClusterId() + " - destroy");

        Marathon marathon = getMarathon();
        if (marathon != null) {
            marathon.killAllApps();
        }

        if (memberProcesses.size() > 0) {
            for (int i = memberProcesses.size() - 1; i >= 0; i--) {
                ClusterProcess container = memberProcesses.get(i);
                LOGGER.debug("Removing container [" + container.getContainerId() + "]");
                try {
                    container.remove();
                } catch (NotFoundException e) {
                    LOGGER.error(String.format("Cannot remove container %s, maybe it's already dead?", container.getContainerId()));
                }
            }
        }
        this.running = false;
        this.memberProcesses.clear();

        if (clusterId != null) {
            factory.destroyRunningCluster(clusterId);

            File sandboxLocation = new File(MesosCluster.getClusterHostDir(), ".minimesos/sandbox-" + clusterId);
            if (sandboxLocation.exists()) {
                try {
                    FileUtils.forceDelete(sandboxLocation);
                } catch (IOException e) {
                    String msg = String.format("Failed to force delete the cluster sandbox at %s", sandboxLocation.getAbsolutePath());
                    throw new MinimesosException(msg, e);
                }
            }

        } else {
            LOGGER.info("Minimesos cluster is not running");
        }

        repository.deleteClusterFile();

        this.running = false;
    }

    /**
     * Starts a container. This container will be removed when the Mesos cluster is shut down.
     *
     * @param process container to be started
     * @param timeout in seconds
     * @return container ID
     */
    public String addAndStartProcess(ClusterProcess process, int timeout) {
        process.setCluster(this);
        memberProcesses.add(process);

        LOGGER.debug(String.format("Starting %s (%s) container", process.getName(), process.getContainerId()));

        try {
            process.start(timeout);
        } catch (Exception exc) {
            String msg = String.format("Failed to start %s (%s) container", process.getName(), process.getContainerId());
            LOGGER.error(msg, exc);
            throw new MinimesosException(msg, exc);
        }

        return process.getContainerId();
    }

    /**
     * Starts a container. This container will be removed when the Mesos cluster is shut down.
     * The method is used by frameworks
     *
     * @param clusterProcess container to be started
     * @return container ID
     */
    public String addAndStartProcess(ClusterProcess clusterProcess) {
        return addAndStartProcess(clusterProcess, clusterConfig.getTimeout());
    }

    /**
     * Retrieves JSON with Mesos Cluster master state
     *
     * @return stage JSON 
     */
    public JSONObject getClusterStateInfo() {
        try {
            return getMaster().getStateInfoJSON();
        } catch (UnirestException e) {
            throw new MinimesosException("Failed to retrieve state from Mesos Master", e);
        }
    }

    /**
     * Retrieves JSON with Mesos state of the given container
     *
     * @param containerId ID of the container to get state from
     * @return stage JSON
     */
    public JSONObject getAgentStateInfo(String containerId) {
        MesosAgent theAgent = null;
        for (MesosAgent agent : getAgents()) {
            if (agent.getContainerId().startsWith(containerId)) {
                if (theAgent == null) {
                    theAgent = agent;
                } else {
                    throw new MinimesosException("Provided ID " + containerId + " is not enough to uniquely identify container");
                }
            }
        }

        try {
            return (theAgent != null) ? theAgent.getStateInfoJSON() : null;
        } catch (UnirestException e) {
            throw new MinimesosException("Failed to retrieve state from Mesos Agent container " + theAgent.getContainerId(), e);
        }
    }

    public List<ClusterProcess> getMemberProcesses() {
        return memberProcesses;
    }

    public List<MesosAgent> getAgents() {
        return memberProcesses.stream().filter(Filter.mesosAgent()).map(c -> (MesosAgent) c).collect(Collectors.toList());
    }

    public MesosMaster getMaster() {
        Optional<MesosMaster> master = getOne(Filter.mesosMaster());
        return master.isPresent() ? master.get() : null;
    }

    public ZooKeeper getZooKeeper() {
        Optional<ZooKeeper> zooKeeper = getOne(Filter.zooKeeper());
        return zooKeeper.isPresent() ? zooKeeper.get() : null;
    }

    public Marathon getMarathon() {
        Optional<Marathon> marathon = getOne(Filter.marathon());
        return marathon.isPresent() ? marathon.get() : null;
    }

    public Consul getConsul() {
        Optional<Consul> container = getOne(Filter.consul());
        return container.isPresent() ? container.get() : null;
    }

    public MesosDns getMesosDns() {
        Optional<MesosDns> container = getOne(Filter.mesosDns());
        return container.isPresent() ? container.get() : null;
    }

    /**
     * Optionally get one of a certain type of type T. Note, this cast will always work because we are filtering on that type.
     * If it doesn't find that type, the optional is empty so the cast doesn't need to be performed.
     *
     * @param filter A predicate that is true when an {@link ClusterProcess} in the list is of type T
     * @param <T>    A container of type T that extends {@link ClusterProcess}
     * @return the first container it comes across.
     */
    @SuppressWarnings("unchecked")
    public <T extends ClusterProcess> Optional<T> getOne(java.util.function.Predicate<ClusterProcess> filter) {
        return (Optional<T>) getMemberProcesses().stream().filter(filter).findFirst();
    }

    public String getClusterId() {
        return clusterId;
    }

    public boolean isMapPortsToHost() {
        return clusterConfig.getMapPortsToHost();
    }

    public boolean getMapAgentSandboxVolume() {
        return clusterConfig.getMapAgentSandboxVolume();
    }

    public void setMapPortsToHost(boolean mapPortsToHost) {
        clusterConfig.setMapPortsToHost(mapPortsToHost);
    }

    public void waitForState(final Predicate<State> predicate) {
        await("Mesos master startup" + clusterConfig.getTimeout()).atMost(clusterConfig.getTimeout(), TimeUnit.SECONDS).until(() -> {
            try {
                assertTrue(predicate.test(State.fromJSON(getMaster().getStateInfoJSON().toString())));
            } catch (InternalServerErrorException | JsonParseException | UnirestException | JsonMappingException e) { //NOSONAR
                throw new AssertionError("Mesos master did not start after " + clusterConfig.getTimeout(), e);
            }
        });
    }

    /**
     * Returns the directory on the host from which the cluster was created.
     *
     * @return directory
     */
    public static File getClusterHostDir() {
        String sp = Sys
Download .txt
gitextract_yszckrba/

├── .editorconfig
├── .gitignore
├── .pullapprove.yml
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── bin/
│   ├── install
│   ├── install-version
│   └── minimesos
├── build.gradle
├── cli/
│   ├── Dockerfile
│   ├── build.gradle
│   └── src/
│       ├── integration-test/
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               └── main/
│       │   │                   ├── CommandInitTest.java
│       │   │                   ├── CommandLogsTest.java
│       │   │                   ├── CommandPsTest.java
│       │   │                   ├── CommandTest.java
│       │   │                   ├── CommandUninstallTest.java
│       │   │                   └── CommandUpTest.java
│       │   └── resources/
│       │       ├── app.json
│       │       ├── clusterconfig/
│       │       │   ├── basic.groovy
│       │       │   └── two-agents.groovy
│       │       ├── configFiles/
│       │       │   ├── complete-minimesosFile
│       │       │   ├── invalid-minimesosFile.txt
│       │       │   ├── marathonAppConfig-minimesosFile
│       │       │   └── withMarathon-minimesosFile
│       │       └── logback-test.xml
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── containersol/
│       │               └── minimesos/
│       │                   └── main/
│       │                       ├── Command.java
│       │                       ├── CommandDestroy.java
│       │                       ├── CommandHelp.java
│       │                       ├── CommandInfo.java
│       │                       ├── CommandInit.java
│       │                       ├── CommandInstall.java
│       │                       ├── CommandLogs.java
│       │                       ├── CommandPs.java
│       │                       ├── CommandState.java
│       │                       ├── CommandUninstall.java
│       │                       ├── CommandUp.java
│       │                       ├── CommandVersion.java
│       │                       └── Main.java
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               └── main/
│           │                   ├── CommandInstallTest.java
│           │                   └── MainTest.java
│           └── resources/
│               ├── app.json
│               └── group.json
├── docs/
│   └── index.md
├── gradle/
│   ├── quality.gradle
│   ├── spock.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── minimesos/
│   ├── build.gradle
│   └── src/
│       ├── integration-test/
│       │   └── java/
│       │       └── com.containersol.minimesos/
│       │           └── integrationtest/
│       │               ├── AuthenticationTest.java
│       │               ├── MesosClusterTest.java
│       │               └── container/
│       │                   ├── HelloWorldContainer.java
│       │                   └── MesosExecuteContainer.java
│       ├── main/
│       │   ├── groovy/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               └── config/
│       │   │                   ├── AgentResourcesConfig.groovy
│       │   │                   ├── AppConfig.groovy
│       │   │                   ├── ClusterConfig.groovy
│       │   │                   ├── ConfigParser.groovy
│       │   │                   ├── ConsulConfig.groovy
│       │   │                   ├── ContainerConfig.groovy
│       │   │                   ├── ContainerConfigBlock.groovy
│       │   │                   ├── GroovyBlock.groovy
│       │   │                   ├── GroupConfig.groovy
│       │   │                   ├── MarathonConfig.groovy
│       │   │                   ├── MesosAgentConfig.groovy
│       │   │                   ├── MesosContainerConfig.groovy
│       │   │                   ├── MesosDNSConfig.groovy
│       │   │                   ├── MesosMasterConfig.groovy
│       │   │                   ├── RegistratorConfig.groovy
│       │   │                   ├── ResourceDef.groovy
│       │   │                   ├── ResourceDefRanges.groovy
│       │   │                   ├── ResourceDefScalar.groovy
│       │   │                   └── ZooKeeperConfig.groovy
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── containersol/
│       │   │           └── minimesos/
│       │   │               ├── MinimesosException.java
│       │   │               ├── cluster/
│       │   │               │   ├── ClusterProcess.java
│       │   │               │   ├── ClusterRepository.java
│       │   │               │   ├── ClusterUtil.java
│       │   │               │   ├── Consul.java
│       │   │               │   ├── Filter.java
│       │   │               │   ├── Marathon.java
│       │   │               │   ├── MesosAgent.java
│       │   │               │   ├── MesosCluster.java
│       │   │               │   ├── MesosClusterFactory.java
│       │   │               │   ├── MesosContainer.java
│       │   │               │   ├── MesosDns.java
│       │   │               │   ├── MesosMaster.java
│       │   │               │   ├── Registrator.java
│       │   │               │   └── ZooKeeper.java
│       │   │               ├── docker/
│       │   │               │   ├── DockerClientFactory.java
│       │   │               │   └── DockerContainersUtil.java
│       │   │               ├── integrationtest/
│       │   │               │   └── container/
│       │   │               │       ├── AbstractContainer.java
│       │   │               │       └── ContainerName.java
│       │   │               ├── junit/
│       │   │               │   └── MesosClusterTestRule.java
│       │   │               ├── marathon/
│       │   │               │   └── MarathonContainer.java
│       │   │               ├── mesos/
│       │   │               │   ├── ClusterContainers.java
│       │   │               │   ├── ConsulContainer.java
│       │   │               │   ├── MesosAgentContainer.java
│       │   │               │   ├── MesosClusterContainersFactory.java
│       │   │               │   ├── MesosContainerImpl.java
│       │   │               │   ├── MesosDnsContainer.java
│       │   │               │   ├── MesosMasterContainer.java
│       │   │               │   ├── RegistratorContainer.java
│       │   │               │   └── ZooKeeperContainer.java
│       │   │               ├── state/
│       │   │               │   ├── Discovery.java
│       │   │               │   ├── Executor.java
│       │   │               │   ├── Framework.java
│       │   │               │   ├── Port.java
│       │   │               │   ├── Ports.java
│       │   │               │   ├── State.java
│       │   │               │   └── Task.java
│       │   │               └── util/
│       │   │                   ├── CollectionsUtils.java
│       │   │                   ├── Downloader.java
│       │   │                   ├── Environment.java
│       │   │                   ├── EnvironmentBuilder.java
│       │   │                   ├── Predicate.java
│       │   │                   └── ResourceUtil.java
│       │   └── resources/
│       │       ├── logback.xml
│       │       └── marathon/
│       │           ├── elasticsearch.json
│       │           └── mesos-consul.json
│       └── test/
│           ├── groovy/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               └── config/
│           │                   ├── AgentResourcesConfigTest.groovy
│           │                   ├── ConfigParserTest.groovy
│           │                   ├── ConfigWriterTest.groovy
│           │                   └── ResourceDefScalarTest.groovy
│           ├── java/
│           │   └── com/
│           │       └── containersol/
│           │           └── minimesos/
│           │               ├── ClusterBuilderTest.java
│           │               ├── ParseStateJSONTest.java
│           │               ├── factory/
│           │               │   └── MesosClusterContainersFactoryTest.java
│           │               ├── integrationtest/
│           │               │   └── container/
│           │               │       ├── ContainerNameTest.java
│           │               │       └── MesosAgentTest.java
│           │               ├── jdepend/
│           │               │   └── JDependCyclesTest.java
│           │               ├── mesos/
│           │               │   ├── ClusterContainersTest.java
│           │               │   └── ClusterUtilTest.java
│           │               └── util/
│           │                   ├── CollectionsUtilsTest.java
│           │                   ├── EnvironmentBuilderTest.java
│           │                   └── ResourceUtilTest.java
│           └── resources/
│               ├── configFiles/
│               │   ├── minimesosFile-authenticationTest
│               │   └── minimesosFile-mesosClusterTest
│               └── logback-test.xml
├── opt/
│   ├── apps/
│   │   └── weave-scope.json
│   ├── sonar/
│   │   ├── DockerFile
│   │   ├── certificate.yaml
│   │   ├── setup.md
│   │   ├── sonar-deployment.yaml
│   │   ├── sonar-plugins/
│   │   │   ├── sonar-github-plugin-1.1.jar
│   │   │   ├── sonar-java-plugin-3.7.1.jar
│   │   │   ├── sonar-scm-git-plugin-1.0.jar
│   │   │   └── sonar-scm-svn-plugin-1.2.jar
│   │   ├── sonar-postgres-deployment.yaml
│   │   ├── sonar-postgres-service.yaml
│   │   └── sonar-service.yaml
│   └── vagrant/
│       └── debian/
│           └── jessie64/
│               ├── Vagrantfile
│               └── provision.sh
├── settings.gradle
└── travis.sh
Download .txt
SYMBOL INDEX (589 symbols across 79 files)

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandInitTest.java
  class CommandInitTest (line 18) | public class CommandInitTest {
    method before (line 22) | @Before
    method testFileContent (line 27) | @Test
    method testExecute_existingMiniMesosFile (line 38) | @Test(expected = MinimesosException.class)
    method testValidateParameters (line 62) | @Test
    method testName (line 67) | @Test

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandLogsTest.java
  class CommandLogsTest (line 26) | public class CommandLogsTest {
    method initTest (line 70) | @Before
    method TestStdout (line 97) | @Test
    method TestUnexistingTask (line 117) | @Test
    method TestStderr (line 134) | @Test
    method generateAgentState (line 154) | private State generateAgentState() {
    method generateMasterState (line 176) | private State generateMasterState() {

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandPsTest.java
  class CommandPsTest (line 27) | public class CommandPsTest {
    method initTest (line 37) | @Before
    method execute (line 43) | @Test

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandTest.java
  class CommandTest (line 22) | public class CommandTest {
    method initTest (line 30) | @Before
    method testUpAndDestroy (line 36) | @Test
    method testUp_invalidMinimesosFile (line 55) | @Test
    method testUp_alreadyRunning (line 74) | @Test
    method testInfo_runningCluster (line 97) | @Test
    method testInfo_notRunning (line 114) | @Test
    method testState (line 123) | @Test
    method testInstallCommandValidation (line 140) | @Test
    method testInstall (line 146) | @Test
    method testInstall_alreadyRunning (line 160) | @Test(expected = MinimesosException.class)
    method testState_notRunning (line 174) | @Test
    method testCompleteInitFile (line 183) | @Test

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandUninstallTest.java
  class CommandUninstallTest (line 21) | public class CommandUninstallTest {
    method initTest (line 31) | @Before
    method execute_app (line 48) | @Test
    method execute_group (line 62) | @Test
    method execute_appAndGroup (line 76) | @Test
    method execute_appDoesNotExist (line 90) | @Test

FILE: cli/src/integration-test/java/com/containersol/minimesos/main/CommandUpTest.java
  class CommandUpTest (line 18) | public class CommandUpTest {
    method before (line 26) | @Before
    method testExecute_missingMinimesosFile (line 39) | @Test(expected = MinimesosException.class)
    method testExecute_invalidMinimesosFile (line 44) | @Test(expected = MinimesosException.class)
    method testBasicClusterConfig (line 50) | @Test
    method testExecute_mapPortsToHost (line 58) | @Test

FILE: cli/src/main/java/com/containersol/minimesos/main/Command.java
  type Command (line 3) | public interface Command {
    method validateParameters (line 10) | boolean validateParameters();
    method getName (line 15) | String getName();
    method execute (line 20) | void execute();

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandDestroy.java
  class CommandDestroy (line 13) | @Parameters(separators = "=", commandDescription = "Destroy a minimesos ...
    method execute (line 22) | @Override
    method validateParameters (line 36) | @Override
    method getName (line 41) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandHelp.java
  class CommandHelp (line 8) | @Parameters(separators = "=", commandDescription = "Display help")
    method execute (line 13) | @Override
    method validateParameters (line 18) | @Override
    method getName (line 23) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInfo.java
  class CommandInfo (line 20) | @Parameters(separators = "=", commandDescription = "Display cluster info...
    method CommandInfo (line 29) | public CommandInfo() { //NOSONAR
    method CommandInfo (line 32) | public CommandInfo(PrintStream ps) {
    method execute (line 36) | @Override
    method printServiceUrls (line 63) | private void printServiceUrls(MesosCluster cluster) {
    method validateParameters (line 88) | @Override
    method getName (line 93) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInit.java
  class CommandInit (line 34) | @Parameters(separators = "=", commandDescription = "Initialize a minimes...
    method validateParameters (line 43) | @Override
    method getName (line 48) | @Override
    method execute (line 53) | @Override
    method getConfigFileContent (line 82) | public String getConfigFileContent() {

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandInstall.java
  class CommandInstall (line 19) | @Parameters(commandDescription = "Install a Marathon application or appl...
    method execute (line 42) | @Override
    method getMarathonJson (line 77) | private String getMarathonJson() throws IOException {
    method validateParameters (line 92) | @Override
    method getName (line 97) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandLogs.java
  class CommandLogs (line 24) | @Parameters(separators = "=", commandDescription = "Fetches the stdout l...
    method CommandLogs (line 39) | public CommandLogs(PrintStream output) {
    method CommandLogs (line 43) | public CommandLogs() {
    method validateParameters (line 47) | @Override
    method getName (line 52) | @Override
    method execute (line 57) | @Override
    method setRepository (line 86) | public void setRepository(ClusterRepository repository) {
    method setDownloader (line 90) | void setDownloader(Downloader downloader) {
    method findTask (line 94) | private Task findTask(State state, String taskId) {
    method findAgent (line 105) | private MesosAgent findAgent(MesosCluster cluster, String slaveId) {
    method getFileUrl (line 115) | private URI getFileUrl(MesosAgent agent, Task task, String filename) t...
    method findExecutor (line 133) | private Executor findExecutor(MesosAgent agent, Task task) {

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandPs.java
  class CommandPs (line 16) | @Parameters(separators = "=", commandDescription = "List running tasks")
    method CommandPs (line 27) | public CommandPs(PrintStream output) {
    method CommandPs (line 31) | public CommandPs() {
    method validateParameters (line 35) | @Override
    method getName (line 40) | @Override
    method execute (line 45) | @Override
    method setRepository (line 63) | public void setRepository(ClusterRepository repository) {

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandState.java
  class CommandState (line 13) | @Parameters(separators = "=", commandDescription = "Display the master's...
    method CommandState (line 22) | public CommandState() { //NOSONAR
    method CommandState (line 25) | public CommandState(PrintStream ps) {
    method execute (line 29) | @Override
    method validateParameters (line 39) | @Override
    method getName (line 44) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandUninstall.java
  class CommandUninstall (line 18) | @Parameters(separators = "=", commandDescription = "Uninstall a Marathon...
    method CommandUninstall (line 31) | CommandUninstall(PrintStream output) {
    method CommandUninstall (line 35) | CommandUninstall() {
    method validateParameters (line 39) | @Override
    method getName (line 44) | @Override
    method execute (line 49) | @Override
    method setRepository (line 87) | public void setRepository(ClusterRepository repository) {
    method setApp (line 91) | void setApp(String app) {
    method setGroup (line 95) | void setGroup(String group) {

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandUp.java
  class CommandUp (line 23) | @Parameters(separators = "=", commandDescription = "Create a minimesos c...
    method CommandUp (line 45) | public CommandUp() {
    method CommandUp (line 49) | public CommandUp(PrintStream ps) {
    method isMapPortsToHost (line 54) | public Boolean isMapPortsToHost() {
    method setMapPortsToHost (line 58) | public void setMapPortsToHost(Boolean mapPortsToHost) {
    method getClusterConfigPath (line 62) | public String getClusterConfigPath() {
    method setClusterConfigPath (line 70) | public void setClusterConfigPath(String clusterConfigPath) {
    method execute (line 74) | @Override
    method readClusterConfigFromMinimesosFile (line 102) | public ClusterConfig readClusterConfigFromMinimesosFile() {
    method updateWithParameters (line 121) | public void updateWithParameters(ClusterConfig clusterConfig) {
    method getCluster (line 135) | public MesosCluster getCluster() {
    method validateParameters (line 139) | @Override
    method getName (line 144) | @Override
    method setMesosClusterFactory (line 149) | public void setMesosClusterFactory(MesosClusterContainersFactory mesos...

FILE: cli/src/main/java/com/containersol/minimesos/main/CommandVersion.java
  class CommandVersion (line 10) | @Parameters(separators = "=", commandDescription = "Display the version ...
    method CommandVersion (line 17) | public CommandVersion() { // NOSONAR
    method CommandVersion (line 21) | public CommandVersion(PrintStream ps) {
    method execute (line 25) | @Override
    method validateParameters (line 32) | @Override
    method getName (line 37) | @Override

FILE: cli/src/main/java/com/containersol/minimesos/main/Main.java
  class Main (line 25) | @Parameters(separators = "=", commandDescription = "Global options")
    method main (line 47) | public static void main(String[] args) {
    method setOutput (line 76) | public void setOutput(PrintStream output) {
    method run (line 80) | int run(String[] args) {
    method initJCommander (line 136) | private void initJCommander() {
    method parseParams (line 143) | private void parseParams(JCommander jc, String[] args) {
    method initializeDebugLogging (line 151) | private static void initializeDebugLogging() {
    method handleNoCommand (line 160) | private int handleNoCommand() {
    method printUsage (line 171) | private void printUsage(String commandName) {
    method addCommand (line 181) | void addCommand(Command command) {

FILE: cli/src/test/java/com/containersol/minimesos/main/CommandInstallTest.java
  class CommandInstallTest (line 18) | public class CommandInstallTest {
    method before (line 28) | @Before
    method testInstallMarathonFile (line 42) | @Test
    method testInstallMarathonApp (line 54) | @Test
    method testInstallMarathonGroup (line 66) | @Test

FILE: cli/src/test/java/com/containersol/minimesos/main/MainTest.java
  class MainTest (line 16) | public class MainTest {
    method before (line 28) | @Before
    method testUp (line 64) | @Test
    method testDestroy (line 70) | @Test
    method testInfo (line 76) | @Test
    method testState (line 82) | @Test
    method testInstall (line 88) | @Test
    method testLogs (line 94) | @Test
    method testLogsNoParameter (line 100) | @Test
    method testUnsupportedCommand (line 107) | @Test
    method testMinusMinusHelp (line 114) | @Test
    method testInstallNoParameters (line 121) | @Test
    method testHelp (line 128) | @Test
    method testNonExistingCommand (line 135) | @Test
    method assertUsageText (line 143) | private static void assertUsageText(String output) {

FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/AuthenticationTest.java
  class AuthenticationTest (line 10) | public class AuthenticationTest {
    method clusterHasZookeeperUrl (line 19) | @Test
    method extraEnvironmentVariablesPassedToMesosMaster (line 28) | @Test

FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/MesosClusterTest.java
  class MesosClusterTest (line 43) | public class MesosClusterTest {
    method after (line 50) | @After
    method testLoadCluster_noContainersFound (line 55) | @Test(expected = MinimesosException.class)
    method mesosClusterCanBeStarted (line 60) | @Test
    method mesosResourcesCorrect (line 68) | @Test
    method dockerExposeResourcesPorts (line 77) | @Test
    method testHelloWorldContainer (line 91) | @Test
    method testMasterLinkedToAgents (line 100) | @Test
    method testStartingClusterSecondTime (line 114) | @Test(expected = IllegalStateException.class)
    method testMesosVersionRestored (line 119) | @Test
    method testFindMesosMaster (line 127) | @Test
    class LogContainerTestCallback (line 141) | private static class LogContainerTestCallback extends LogContainerResu...
      method onNext (line 144) | @Override
      method toString (line 150) | @Override
    method testMesosExecuteContainerSuccess (line 156) | @Test
    method noMarathonTest (line 171) | @Test
    method stopWithNewContainerTest (line 181) | @Test
    method testStartTwiceShouldNoOp (line 194) | @Test

FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/HelloWorldContainer.java
  class HelloWorldContainer (line 11) | public class HelloWorldContainer extends AbstractContainer {
    method HelloWorldContainer (line 17) | public HelloWorldContainer() {
    method getRole (line 21) | @Override
    method dockerCommand (line 26) | @Override

FILE: minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/MesosExecuteContainer.java
  class MesosExecuteContainer (line 10) | public class MesosExecuteContainer extends AbstractContainer {
    method MesosExecuteContainer (line 14) | public MesosExecuteContainer() {
    method getRole (line 18) | @Override
    method dockerCommand (line 23) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/MinimesosException.java
  class MinimesosException (line 6) | public class MinimesosException extends RuntimeException {
    method MinimesosException (line 8) | public MinimesosException(String message) {
    method MinimesosException (line 12) | public MinimesosException(String message, Throwable cause) {

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterProcess.java
  type ClusterProcess (line 8) | public interface ClusterProcess {
    method getCluster (line 10) | MesosCluster getCluster();
    method setCluster (line 12) | void setCluster(MesosCluster mesosCluster);
    method getIpAddress (line 17) | String getIpAddress();
    method getServiceUrl (line 22) | URI getServiceUrl();
    method getName (line 29) | String getName();
    method getContainerId (line 34) | String getContainerId();
    method start (line 41) | void start(int timeout);
    method getRole (line 43) | String getRole();
    method remove (line 48) | void remove();

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterRepository.java
  class ClusterRepository (line 16) | public class ClusterRepository {
    method loadCluster (line 27) | public MesosCluster loadCluster(MesosClusterFactory factory) {
    method saveClusterFile (line 44) | public void saveClusterFile(MesosCluster cluster) {
    method deleteClusterFile (line 61) | public void deleteClusterFile() {
    method readClusterId (line 65) | public String readClusterId() {
    method getMinimesosFile (line 79) | public File getMinimesosFile() {
    method getMinimesosDir (line 86) | public File getMinimesosDir() {
    method deleteMinimesosFile (line 98) | private void deleteMinimesosFile() {

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterUtil.java
  class ClusterUtil (line 14) | public class ClusterUtil {
    method ClusterUtil (line 19) | private ClusterUtil() {
    method getDistinctRoleProcesses (line 28) | public static List<ClusterProcess> getDistinctRoleProcesses(List<Clust...

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Consul.java
  type Consul (line 6) | public interface Consul extends ClusterProcess {

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Filter.java
  class Filter (line 5) | public class Filter {
    method Filter (line 7) | private Filter() {
    method zooKeeper (line 10) | public static Predicate<ClusterProcess> zooKeeper() {
    method consul (line 14) | public static Predicate<ClusterProcess> consul() {
    method mesosMaster (line 18) | public static Predicate<ClusterProcess> mesosMaster() {
    method mesosAgent (line 22) | public static Predicate<ClusterProcess> mesosAgent() {
    method marathon (line 26) | public static Predicate<ClusterProcess> marathon() {
    method withRole (line 30) | public static Predicate<ClusterProcess> withRole(String role) {
    method registrator (line 34) | public static Predicate<ClusterProcess> registrator() { return process...
    method mesosDns (line 36) | public static Predicate<ClusterProcess> mesosDns() {

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Marathon.java
  type Marathon (line 10) | public interface Marathon extends ClusterProcess {
    method installMarathonApps (line 15) | void installMarathonApps();
    method deployApp (line 22) | void deployApp(String marathonJson);
    method updateApp (line 29) | void updateApp(String marathonJson);
    method killAllApps (line 34) | void killAllApps();
    method setZooKeeper (line 36) | void setZooKeeper(ZooKeeper zookeeper);
    method deleteApp (line 43) | Result deleteApp(String app);
    method deployGroup (line 50) | void deployGroup(String groupJson);
    method deleteGroup (line 57) | Result deleteGroup(String group);

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosAgent.java
  type MesosAgent (line 6) | public interface MesosAgent extends MesosContainer {
    method getResources (line 7) | String getResources();

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosCluster.java
  class MesosCluster (line 41) | public class MesosCluster {
    method MesosCluster (line 63) | public MesosCluster(ClusterConfig clusterConfig, List<ClusterProcess> ...
    method loadCluster (line 78) | public static MesosCluster loadCluster(String clusterId, MesosClusterF...
    method MesosCluster (line 87) | private MesosCluster(String clusterId, MesosClusterFactory factory) {
    method start (line 121) | public void start() {
    method start (line 130) | public void start(int timeoutSeconds) {
    method state (line 156) | public void state(PrintStream out) {
    method destroy (line 168) | public void destroy(MesosClusterFactory factory) {
    method addAndStartProcess (line 219) | public String addAndStartProcess(ClusterProcess process, int timeout) {
    method addAndStartProcess (line 243) | public String addAndStartProcess(ClusterProcess clusterProcess) {
    method getClusterStateInfo (line 252) | public JSONObject getClusterStateInfo() {
    method getAgentStateInfo (line 266) | public JSONObject getAgentStateInfo(String containerId) {
    method getMemberProcesses (line 285) | public List<ClusterProcess> getMemberProcesses() {
    method getAgents (line 289) | public List<MesosAgent> getAgents() {
    method getMaster (line 293) | public MesosMaster getMaster() {
    method getZooKeeper (line 298) | public ZooKeeper getZooKeeper() {
    method getMarathon (line 303) | public Marathon getMarathon() {
    method getConsul (line 308) | public Consul getConsul() {
    method getMesosDns (line 313) | public MesosDns getMesosDns() {
    method getOne (line 326) | @SuppressWarnings("unchecked")
    method getClusterId (line 331) | public String getClusterId() {
    method isMapPortsToHost (line 335) | public boolean isMapPortsToHost() {
    method getMapAgentSandboxVolume (line 339) | public boolean getMapAgentSandboxVolume() {
    method setMapPortsToHost (line 343) | public void setMapPortsToHost(boolean mapPortsToHost) {
    method waitForState (line 347) | public void waitForState(final Predicate<State> predicate) {
    method getClusterHostDir (line 362) | public static File getClusterHostDir() {
    method getInputStream (line 376) | public static InputStream getInputStream(String location) {
    method getLoggingLevel (line 422) | public String getLoggingLevel() {
    method getConfiguredMesosVersion (line 429) | public String getConfiguredMesosVersion() {
    method getMesosVersion (line 436) | public String getMesosVersion() {
    method getClusterName (line 443) | public String getClusterName() {
    method getClusterConfig (line 451) | public ClusterConfig getClusterConfig() {
    method equals (line 455) | @Override
    method hashCode (line 465) | @Override
    method toString (line 471) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosClusterFactory.java
  class MesosClusterFactory (line 6) | public abstract class MesosClusterFactory {
    method loadRunningCluster (line 13) | public abstract void loadRunningCluster(MesosCluster cluster);
    method destroyRunningCluster (line 20) | public abstract void destroyRunningCluster(String clusterId);

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosContainer.java
  type MesosContainer (line 10) | public interface MesosContainer extends ClusterProcess {
    method setZooKeeper (line 12) | void setZooKeeper(ZooKeeper zookeeper);
    method getStateInfoJSON (line 14) | JSONObject getStateInfoJSON() throws UnirestException;
    method getState (line 21) | State getState();

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosDns.java
  type MesosDns (line 6) | public interface MesosDns extends ClusterProcess {

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/MesosMaster.java
  type MesosMaster (line 6) | public interface MesosMaster extends MesosContainer {
    method getStateUrl (line 8) | String getStateUrl();
    method waitFor (line 10) | void waitFor();

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/Registrator.java
  type Registrator (line 6) | public interface Registrator extends ClusterProcess {
    method setConsul (line 8) | void setConsul(Consul consul);

FILE: minimesos/src/main/java/com/containersol/minimesos/cluster/ZooKeeper.java
  type ZooKeeper (line 6) | public interface ZooKeeper extends ClusterProcess {
    method getFormattedZKAddress (line 11) | String getFormattedZKAddress();

FILE: minimesos/src/main/java/com/containersol/minimesos/docker/DockerClientFactory.java
  class DockerClientFactory (line 12) | public class DockerClientFactory {
    method build (line 16) | public static DockerClient build() {

FILE: minimesos/src/main/java/com/containersol/minimesos/docker/DockerContainersUtil.java
  class DockerContainersUtil (line 26) | public class DockerContainersUtil {
    method DockerContainersUtil (line 30) | private DockerContainersUtil(List<Container> containers) {
    method getContainers (line 39) | public List<Container> getContainers() {
    method getContainers (line 47) | public static DockerContainersUtil getContainers(boolean showAll) {
    method size (line 52) | public int size() {
    method filterByName (line 62) | public DockerContainersUtil filterByName(String pattern) {
    method filterByImage (line 87) | public DockerContainersUtil filterByImage(String pattern) {
    method remove (line 105) | public void remove() {
    method kill (line 116) | public DockerContainersUtil kill() {
    method kill (line 125) | public DockerContainersUtil kill(boolean ignoreFailure) {
    method getIpAddresses (line 143) | public Set<String> getIpAddresses() {
    method getIpAddress (line 157) | public static String getIpAddress(String containerId) {
    method getDockerLogs (line 168) | public static List<String> getDockerLogs(String containerId) {
    method pullImage (line 195) | public static void pullImage(String imageName, String imageVersion, lo...
    method getGatewayIpAddress (line 207) | public static String getGatewayIpAddress(String containerId) {
    method getContainer (line 216) | public static Container getContainer(String containerId) {

FILE: minimesos/src/main/java/com/containersol/minimesos/integrationtest/container/AbstractContainer.java
  class AbstractContainer (line 29) | public abstract class AbstractContainer implements ClusterProcess {
    method AbstractContainer (line 41) | protected AbstractContainer(ContainerConfig config) {
    method AbstractContainer (line 46) | public AbstractContainer(MesosCluster cluster, String uuid, String con...
    method pullImage (line 56) | public void pullImage() {
    method getImageName (line 63) | public String getImageName() {
    method getImageTag (line 70) | public String getImageTag() {
    method dockerCommand (line 79) | protected abstract CreateContainerCmd dockerCommand();
    method start (line 86) | @Override
    method getContainerId (line 131) | @Override
    method getServiceUrl (line 136) | @Override
    method getServiceProtocol (line 161) | protected String getServiceProtocol() {
    method getServicePort (line 169) | protected int getServicePort() {
    method getServicePath (line 177) | protected String getServicePath() {
    method getIpAddress (line 184) | @Override
    method retrieveIpAddress (line 192) | private synchronized void retrieveIpAddress() {
    method getName (line 205) | @Override
    method remove (line 213) | @Override
    method imageExists (line 224) | protected Boolean imageExists(String imageName, String registryTag) {
    method pullImage (line 242) | protected void pullImage(String imageName, String registryTag) {
    method setCluster (line 257) | @Override
    method getCluster (line 262) | @Override
    method getClusterId (line 270) | public String getClusterId() {
    method toString (line 274) | @Override
    method getUuid (line 279) | public String getUuid() {
    method equals (line 283) | @Override
    method hashCode (line 296) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/integrationtest/container/ContainerName.java
  class ContainerName (line 6) | public class ContainerName {
    method ContainerName (line 9) | private ContainerName() {
    method getContainerNamePattern (line 12) | public static String getContainerNamePattern(String clusterId) {
    method get (line 20) | public static String get(AbstractContainer container) {
    method hasRoleInCluster (line 32) | public static boolean hasRoleInCluster(String containerName, String cl...
    method hasRoleInCluster (line 45) | public static boolean hasRoleInCluster(String[] dockerNames, String cl...
    method belongsToCluster (line 53) | public static boolean belongsToCluster(String containerName, String cl...
    method belongsToCluster (line 61) | public static boolean belongsToCluster(String[] dockerNames, String cl...
    method getFromDockerNames (line 73) | public static String getFromDockerNames(String[] dockerNames) {

FILE: minimesos/src/main/java/com/containersol/minimesos/junit/MesosClusterTestRule.java
  class MesosClusterTestRule (line 20) | public class MesosClusterTestRule implements TestRule {
    method fromClassPath (line 26) | public static MesosClusterTestRule fromClassPath(String path) {
    method fromFile (line 35) | public static MesosClusterTestRule fromFile(String minimesosFilePath) {
    method MesosClusterTestRule (line 44) | private MesosClusterTestRule(MesosCluster mesosCluster) {
    method apply (line 55) | @Override
    method before (line 73) | protected void before() {
    method after (line 86) | protected void after() {
    method stop (line 93) | public void stop() {
    method getMesosCluster (line 97) | public MesosCluster getMesosCluster() {
    method getFactory (line 101) | public MesosClusterFactory getFactory() {

FILE: minimesos/src/main/java/com/containersol/minimesos/marathon/MarathonContainer.java
  class MarathonContainer (line 51) | public class MarathonContainer extends AbstractContainer implements Mara...
    method MarathonContainer (line 65) | public MarathonContainer(MarathonConfig config) {
    method MarathonContainer (line 70) | public MarathonContainer(MesosCluster cluster, String uuid, String con...
    method MarathonContainer (line 74) | private MarathonContainer(MesosCluster cluster, String uuid, String co...
    method getRole (line 79) | @Override
    method setZooKeeper (line 84) | @Override
    method getServiceUrl (line 89) | @Override
    method dockerCommand (line 116) | @Override
    method getMarathonEndpoint (line 136) | private String getMarathonEndpoint() {
    method deployApp (line 145) | @Override
    method deleteApp (line 156) | @Override
    method deployGroup (line 168) | @Override
    method deleteGroup (line 180) | @Override
    method updateApp (line 197) | @Override
    method constructGroup (line 209) | private Group constructGroup(String groupJson) {
    method constructApp (line 214) | private App constructApp(String appJson) {
    method replaceTokens (line 226) | public String replaceTokens(String source) {
    method replaceToken (line 248) | private static String replaceToken(String input, String token, String ...
    method killAllApps (line 256) | @Override
    method getServicePort (line 282) | @Override
    method waitFor (line 287) | @SuppressWarnings("WeakerAccess")
    method getConfig (line 293) | public MarathonConfig getConfig() {
    class MarathonApiIsReady (line 297) | private class MarathonApiIsReady implements Callable<Boolean> {
      method call (line 298) | @Override
    method installMarathonApps (line 313) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/ClusterContainers.java
  class ClusterContainers (line 13) | public class ClusterContainers {
    method ClusterContainers (line 20) | public ClusterContainers() {
    method ClusterContainers (line 29) | public ClusterContainers(List<ClusterProcess> containers) {
    method add (line 39) | public ClusterContainers add(ClusterProcess container) {
    method getContainers (line 44) | public List<ClusterProcess> getContainers() {
    method getOne (line 56) | @SuppressWarnings("unchecked")
    method isPresent (line 67) | public Boolean isPresent(Predicate<ClusterProcess> filter) {

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/ConsulContainer.java
  class ConsulContainer (line 21) | public class ConsulContainer extends AbstractContainer implements Consul {
    method ConsulContainer (line 25) | public ConsulContainer(ConsulConfig config) {
    method ConsulContainer (line 30) | public ConsulContainer(MesosCluster cluster, String uuid, String conta...
    method ConsulContainer (line 34) | private ConsulContainer(MesosCluster cluster, String uuid, String cont...
    method getRole (line 39) | @Override
    method getServicePort (line 44) | @Override
    method getServiceUrl (line 49) | @Override
    method dockerCommand (line 76) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/MesosAgentContainer.java
  class MesosAgentContainer (line 33) | public class MesosAgentContainer extends MesosContainerImpl implements M...
    method MesosAgentContainer (line 41) | public MesosAgentContainer(MesosAgentConfig agentConfig) {
    method MesosAgentContainer (line 47) | public MesosAgentContainer(MesosCluster cluster, String uuid, String c...
    method MesosAgentContainer (line 51) | private MesosAgentContainer(MesosCluster cluster, String uuid, String ...
    method getResources (line 56) | @Override
    method getAttributeString (line 61) | public String getAttributeString(){
    method getConfig (line 65) | public MesosAgentConfig getConfig() {
    method getServicePort (line 69) | @Override
    method getBaseCommand (line 74) | private CreateContainerCmd getBaseCommand() {
    method getRole (line 104) | @Override
    method dockerCommand (line 109) | @Override
    method getMesosAgentEnvVars (line 123) | private Map<String, String> getMesosAgentEnvVars() {

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/MesosClusterContainersFactory.java
  class MesosClusterContainersFactory (line 38) | public class MesosClusterContainersFactory extends MesosClusterFactory {
    method createZooKeeper (line 42) | public ZooKeeper createZooKeeper(MesosCluster mesosCluster, String uui...
    method createMesosAgent (line 46) | public MesosAgent createMesosAgent(MesosCluster mesosCluster, String u...
    method createMesosMaster (line 50) | public MesosMaster createMesosMaster(MesosCluster mesosCluster, String...
    method createMarathon (line 54) | public Marathon createMarathon(MesosCluster mesosCluster, String uuid,...
    method createConsul (line 58) | public Consul createConsul(MesosCluster mesosCluster, String uuid, Str...
    method createRegistrator (line 62) | public Registrator createRegistrator(MesosCluster mesosCluster, String...
    method createMesosDns (line 66) | public MesosDns createMesosDns(MesosCluster cluster, String uuid, Stri...
    method loadRunningCluster (line 70) | @Override
    method restoreMapToPorts (line 120) | private void restoreMapToPorts(MesosCluster cluster, Container contain...
    method destroyRunningCluster (line 132) | @Override
    method createMesosCluster (line 137) | public MesosCluster createMesosCluster(String path) {
    method createMesosCluster (line 146) | public MesosCluster createMesosCluster(InputStream inputStream) {
    method createMesosCluster (line 155) | public MesosCluster createMesosCluster(ClusterConfig clusterConfig) {
    method createProcesses (line 168) | private static ClusterContainers createProcesses(ClusterConfig cluster...
    method validateProcesses (line 200) | private static void validateProcesses(ClusterContainers clusterContain...
    method connectProcesses (line 220) | private static void connectProcesses(ClusterContainers clusterContaine...
    method isPresent (line 244) | private static Boolean isPresent(ClusterContainers clusterContainers, ...

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/MesosContainerImpl.java
  class MesosContainerImpl (line 27) | public abstract class MesosContainerImpl extends AbstractContainer imple...
    method MesosContainerImpl (line 32) | protected MesosContainerImpl(MesosContainerConfig config) {
    method MesosContainerImpl (line 37) | protected MesosContainerImpl(MesosCluster cluster, String uuid, String...
    method getImageTag (line 42) | @Override
    method getSharedEnvVars (line 51) | protected final Map<String, String> getSharedEnvVars() {
    method setZooKeeper (line 62) | @Override
    method getZooKeeper (line 67) | public ZooKeeper getZooKeeper() {
    method getFormattedZKAddress (line 71) | public String getFormattedZKAddress() {
    method getStateUrl (line 75) | public String getStateUrl() {
    method getStateInfoJSON (line 79) | @Override
    method getLoggingLevel (line 87) | public String getLoggingLevel() {
    method getState (line 95) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/MesosDnsContainer.java
  class MesosDnsContainer (line 20) | public class MesosDnsContainer extends AbstractContainer implements Meso...
    method MesosDnsContainer (line 30) | public MesosDnsContainer(MesosCluster cluster, String uuid, String con...
    method MesosDnsContainer (line 34) | private MesosDnsContainer(MesosCluster cluster, String uuid, String co...
    method MesosDnsContainer (line 39) | public MesosDnsContainer(MesosDNSConfig mesosDNS) {
    method getRole (line 44) | @Override
    method dockerCommand (line 49) | @Override
    method getServicePort (line 62) | @Override
    method getMesosDNSEnvVars (line 67) | private Map<String,String> getMesosDNSEnvVars() {

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/MesosMasterContainer.java
  class MesosMasterContainer (line 33) | public class MesosMasterContainer extends MesosContainerImpl implements ...
    method MesosMasterContainer (line 35) | public MesosMasterContainer(MesosCluster cluster, String uuid, String ...
    method MesosMasterContainer (line 39) | private MesosMasterContainer(MesosCluster cluster, String uuid, String...
    method MesosMasterContainer (line 43) | public MesosMasterContainer(MesosMasterConfig master) {
    method getServicePort (line 47) | @Override
    method getServiceUrl (line 52) | @Override
    method getMesosMasterEnvVars (line 80) | protected Map<String, String> getMesosMasterEnvVars() {
    method getRole (line 95) | @Override
    method dockerCommand (line 100) | @Override
    method waitFor (line 127) | @Override
    class MesosClusterStateResponse (line 132) | public static class MesosClusterStateResponse implements Callable<Bool...
      method MesosClusterStateResponse (line 138) | public MesosClusterStateResponse(MesosCluster mesosCluster) {
      method call (line 142) | @Override
      method waitFor (line 164) | public void waitFor() {

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/RegistratorContainer.java
  class RegistratorContainer (line 16) | public class RegistratorContainer extends AbstractContainer implements R...
    method RegistratorContainer (line 22) | public RegistratorContainer(MesosCluster cluster, String uuid, String ...
    method RegistratorContainer (line 26) | private RegistratorContainer(MesosCluster cluster, String uuid, String...
    method RegistratorContainer (line 31) | public RegistratorContainer(RegistratorConfig registrator) {
    method getRole (line 36) | @Override
    method dockerCommand (line 41) | @Override
    method setConsul (line 50) | public void setConsul(ConsulContainer consul) {
    method setConsul (line 54) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/mesos/ZooKeeperContainer.java
  class ZooKeeperContainer (line 21) | public class ZooKeeperContainer extends AbstractContainer implements Zoo...
    method ZooKeeperContainer (line 25) | public ZooKeeperContainer(ZooKeeperConfig config) {
    method ZooKeeperContainer (line 30) | protected ZooKeeperContainer() {
    method ZooKeeperContainer (line 34) | public ZooKeeperContainer(MesosCluster cluster, String uuid, String co...
    method ZooKeeperContainer (line 38) | public ZooKeeperContainer(MesosCluster cluster, String uuid, String co...
    method getRole (line 43) | @Override
    method dockerCommand (line 48) | @Override
    method getServiceProtocol (line 64) | @Override
    method getServicePort (line 69) | @Override
    method getServicePath (line 74) | @Override
    method getFormattedZKAddress (line 82) | @Override
    method getServiceUrl (line 87) | @Override

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Discovery.java
  class Discovery (line 8) | @JsonIgnoreProperties(ignoreUnknown = true)
    method getPorts (line 13) | public Ports getPorts() {
    method setPorts (line 17) | public void setPorts(Ports ports) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Executor.java
  class Executor (line 5) | @JsonIgnoreProperties(ignoreUnknown = true)
    method getId (line 11) | public String getId() {
    method setId (line 15) | public void setId(String id) {
    method getDirectory (line 19) | public String getDirectory() {
    method setDirectory (line 23) | public void setDirectory(String directory) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Framework.java
  class Framework (line 11) | @JsonIgnoreProperties(ignoreUnknown = true)
    method isActive (line 32) | public boolean isActive() {
    method setActive (line 36) | public void setActive(boolean active) {
    method isCheckpoint (line 40) | public boolean isCheckpoint() {
    method setCheckpoint (line 44) | public void setCheckpoint(boolean checkpoint) {
    method getFailoverTimeout (line 48) | public int getFailoverTimeout() {
    method setFailoverTimeout (line 52) | public void setFailoverTimeout(int failoverTimeout) {
    method getHostname (line 56) | public String getHostname() {
    method setHostname (line 60) | public void setHostname(String hostname) {
    method getId (line 64) | public String getId() {
    method setId (line 68) | public void setId(String id) {
    method getName (line 72) | public String getName() {
    method setName (line 76) | public void setName(String name) {
    method getRole (line 80) | public String getRole() {
    method setRole (line 84) | public void setRole(String role) {
    method getTasks (line 88) | public ArrayList<Task> getTasks() {
    method setTasks (line 92) | public void setTasks(ArrayList<Task> tasks) {
    method getExecutors (line 96) | public ArrayList<Executor> getExecutors() {
    method setExecutors (line 100) | public void setExecutors(ArrayList<Executor> executors) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Port.java
  class Port (line 8) | @JsonIgnoreProperties(ignoreUnknown = true)
    method getNumber (line 15) | public int getNumber() {
    method setNumber (line 19) | public void setNumber(int number) {
    method getProtocol (line 23) | public String getProtocol() {
    method setProtocol (line 27) | public void setProtocol(String protocol) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Ports.java
  class Ports (line 10) | @JsonIgnoreProperties(ignoreUnknown = true)
    method getPorts (line 15) | public List<Port> getPorts() {
    method setPorts (line 19) | public void setPorts(List<Port> ports) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/State.java
  class State (line 17) | @JsonIgnoreProperties(ignoreUnknown = true)
    method fromJSON (line 31) | public static State fromJSON(String jsonString) throws JsonParseExcept...
    method getFrameworks (line 40) | public ArrayList<Framework> getFrameworks() {
    method setFrameworks (line 44) | public void setFrameworks(ArrayList<Framework> frameworks) {
    method getFramework (line 48) | public Framework getFramework(String name) {
    method getFlags (line 55) | public Map<String, String> getFlags() {
    method getActivatedAgents (line 59) | public int getActivatedAgents() {
    method getVersion (line 63) | public String getVersion() {
    method getId (line 67) | public String getId() {
    method setId (line 71) | public void setId(String id) {

FILE: minimesos/src/main/java/com/containersol/minimesos/state/Task.java
  class Task (line 9) | @JsonIgnoreProperties(ignoreUnknown = true)
    method getId (line 27) | public String getId() {
    method setId (line 31) | public void setId(String id) {
    method getState (line 35) | public String getState() {
    method setState (line 39) | public void setState(String state) {
    method getName (line 43) | public String getName() {
    method setName (line 47) | public void setName(String name) {
    method getFrameworkId (line 51) | public String getFrameworkId() {
    method setFrameworkId (line 55) | public void setFrameworkId(String frameworkId) {
    method getExecutorId (line 59) | public String getExecutorId() {
    method setExecutorId (line 63) | public void setExecutorId(String executorId) {
    method getSlaveId (line 67) | public String getSlaveId() {
    method setSlaveId (line 71) | public void setSlaveId(String slaveId) {
    method getDiscovery (line 75) | public Discovery getDiscovery() {
    method setDiscovery (line 79) | public void setDiscovery(Discovery discovery) {

FILE: minimesos/src/main/java/com/containersol/minimesos/util/CollectionsUtils.java
  class CollectionsUtils (line 14) | public class CollectionsUtils {
    method CollectionsUtils (line 18) | private CollectionsUtils() {
    method typedList (line 22) | public static <T> List<T> typedList(List original, Class<T> clazz) {
    method splitCmd (line 45) | public static String[] splitCmd(String cmd) {

FILE: minimesos/src/main/java/com/containersol/minimesos/util/Downloader.java
  class Downloader (line 11) | public class Downloader {
    method getFileContentAsString (line 13) | public String getFileContentAsString(String url) throws MinimesosExcep...

FILE: minimesos/src/main/java/com/containersol/minimesos/util/Environment.java
  class Environment (line 6) | public class Environment {
    method Environment (line 8) | private Environment() {
    method isRunningInJvmOnMacOsX (line 17) | public static boolean isRunningInJvmOnMacOsX() {
    method isRunningInDockerOnMac (line 26) | public static boolean isRunningInDockerOnMac() {

FILE: minimesos/src/main/java/com/containersol/minimesos/util/EnvironmentBuilder.java
  class EnvironmentBuilder (line 10) | public class EnvironmentBuilder {
    method newEnvironment (line 14) | public static EnvironmentBuilder newEnvironment() {
    method withValue (line 18) | public EnvironmentBuilder withValue(String key, String value) {
    method withValues (line 23) | public EnvironmentBuilder withValues(Map<String, String> envMap) {
    method createEnvironment (line 28) | public String[] createEnvironment() {

FILE: minimesos/src/main/java/com/containersol/minimesos/util/Predicate.java
  type Predicate (line 3) | public interface Predicate<T> {
    method test (line 4) | boolean test(T t);

FILE: minimesos/src/main/java/com/containersol/minimesos/util/ResourceUtil.java
  class ResourceUtil (line 11) | public class ResourceUtil {
    method ResourceUtil (line 13) | private ResourceUtil() {
    method parsePorts (line 26) | public static ArrayList<Integer> parsePorts(String mesosResourceString) {

FILE: minimesos/src/test/java/com/containersol/minimesos/ClusterBuilderTest.java
  class ClusterBuilderTest (line 15) | public class ClusterBuilderTest {
    method testInheritedImageTag (line 17) | @Test
    method testDefaultInAgentLoggingLevel (line 37) | @Test
    method testInheritedLoggingLevel (line 57) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/ParseStateJSONTest.java
  class ParseStateJSONTest (line 12) | public class ParseStateJSONTest {
    method exampleStateJSONIsParsedCorrectly (line 293) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/factory/MesosClusterContainersFactoryTest.java
  class MesosClusterContainersFactoryTest (line 13) | public class MesosClusterContainersFactoryTest {
    method testCreateMesosCluster (line 15) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/integrationtest/container/ContainerNameTest.java
  class ContainerNameTest (line 13) | public class ContainerNameTest {
    method before (line 18) | @Before
    method testBelongsToCluster (line 25) | @Test
    method testWrongCluster (line 34) | @Test
    method testWrongRole (line 43) | @Test
    method testSimpleContainerName (line 52) | @Test
    method testLinkedContainerNames (line 60) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/integrationtest/container/MesosAgentTest.java
  class MesosAgentTest (line 10) | public class MesosAgentTest {
    method testPullingWrongContainer (line 15) | @Test(expected = MinimesosException.class, timeout = 60 * 1000)
    method testPullingWrongContainerMessage (line 27) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/jdepend/JDependCyclesTest.java
  class JDependCyclesTest (line 16) | public class JDependCyclesTest {
    method before (line 22) | @Before
    method testAllPackages (line 32) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/mesos/ClusterContainersTest.java
  class ClusterContainersTest (line 20) | public class ClusterContainersTest {
    method shouldEmptyStart (line 21) | @Test
    method shouldAllowInjection (line 26) | @Test
    method shouldFilterZooKeeper (line 32) | @Test
    method shouldFilterMesosMaster (line 42) | @Test
    method shouldFilterMesosAgent (line 52) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/mesos/ClusterUtilTest.java
  class ClusterUtilTest (line 22) | public class ClusterUtilTest {
    method testGetDistinctRoleProcesses (line 24) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/util/CollectionsUtilsTest.java
  class CollectionsUtilsTest (line 9) | public class CollectionsUtilsTest {
    method testSplitCmd_uncoherentCommandLine (line 11) | @Test(expected = MinimesosException.class)
    method testSplitCmd_cmdLineEmpty (line 16) | @Test
    method testSplitCmd_cmdLineNoQuotes (line 24) | @Test
    method testSplitCmd_cmdLineWithQuotes (line 32) | @Test
    method testSplitCmd_cmdLineWithDoubleQuotes (line 40) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/util/EnvironmentBuilderTest.java
  class EnvironmentBuilderTest (line 12) | public class EnvironmentBuilderTest {
    method mergingSeveralSourcesProducesCorrectMap (line 14) | @Test

FILE: minimesos/src/test/java/com/containersol/minimesos/util/ResourceUtilTest.java
  class ResourceUtilTest (line 10) | public class ResourceUtilTest {
    method testParsePorts_emptyResourceString (line 12) | @Test(expected = MinimesosException.class)
    method testParsePorts_nullResource (line 17) | @Test(expected = MinimesosException.class)
    method testParsePorts_singlePortRange (line 22) | @Test
    method testParsePorts_portRange (line 29) | @Test
    method testParsePorts_portRanges (line 38) | @Test(expected = MinimesosException.class)
Condensed preview — 155 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (373K chars).
[
  {
    "path": ".editorconfig",
    "chars": 157,
    "preview": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\ntrim_trailing_whitespace = true\n\n[*.java]\n"
  },
  {
    "path": ".gitignore",
    "chars": 385,
    "preview": "minimesosFile\n.minimesos/*\n*.class\n.gradle/\nbuild/\n\n# Vagrant working files\n.vagrant\n\n# Build system\n.gradle/\nbuild/\n\n# "
  },
  {
    "path": ".pullapprove.yml",
    "chars": 271,
    "preview": "approve_by_comment: true\napprove_regex: ^(Approved|LGTM|:\\+1:)\nauthor_approval: ignored\nreject_regex: ^Rejected\nreset_on"
  },
  {
    "path": ".travis.yml",
    "chars": 1768,
    "preview": "language: java\n\njdk:\n  - oraclejdk8\n\nsudo: required\n\ninstall:\n# one liner installation of docker 1.9.1 below did not wor"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 769,
    "preview": "default: build\n.PHONY: setup deps test build\n\nsetup:\n\tsudo route delete 172.17.0.0/16; sudo route -n add 172.17.0.0/16 $"
  },
  {
    "path": "README.md",
    "chars": 1645,
    "preview": "# minimesos [![Build Status](https://travis-ci.org/ContainerSolutions/minimesos.svg?branch=master)](https://travis-ci.or"
  },
  {
    "path": "bin/install",
    "chars": 1480,
    "preview": "#!/bin/sh\n\n# This script is meant for quick & easy install via:\n# `sudo curl -sSL https://raw.githubusercontent.com/Cont"
  },
  {
    "path": "bin/install-version",
    "chars": 1147,
    "preview": "#!/bin/sh\n\n# This script is meant to be invoked with VERSION given as a parameter.\n# Installs the given version of minim"
  },
  {
    "path": "bin/minimesos",
    "chars": 2150,
    "preview": "#!/usr/bin/env bash\n\nset -e\n\nMINIMESOS_TAG=\"latest\"\nPARAMS=\"$@\"\nMINIMESOS_CLI_IMAGE=\"containersol/minimesos-cli\"\n\ncomman"
  },
  {
    "path": "build.gradle",
    "chars": 6177,
    "preview": "buildscript {\n\n    repositories {\n        maven {\n            url \"http://dl.bintray.com/gesellix/gradle-plugins\"\n      "
  },
  {
    "path": "cli/Dockerfile",
    "chars": 464,
    "preview": "FROM debian:jessie-backports\nFROM openjdk:8-jre-alpine\nMAINTAINER Container Solutions BV <info@container-solutions.com>\n"
  },
  {
    "path": "cli/build.gradle",
    "chars": 3074,
    "preview": "apply plugin: 'application'\n\nimport com.bmuschko.gradle.docker.tasks.image.DockerBuildImage\nimport com.bmuschko.gradle.d"
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandInitTest.java",
    "chars": 2594,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol."
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandLogsTest.java",
    "chars": 7429,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.cluster.ClusterRepository;\nimport com.contai"
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandPsTest.java",
    "chars": 3024,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.cluster.ClusterRepository;\nimport com.contai"
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandTest.java",
    "chars": 7003,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol."
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandUninstallTest.java",
    "chars": 3175,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol."
  },
  {
    "path": "cli/src/integration-test/java/com/containersol/minimesos/main/CommandUpTest.java",
    "chars": 2331,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol."
  },
  {
    "path": "cli/src/integration-test/resources/app.json",
    "chars": 92,
    "preview": "{\n  \"id\": \"hello\",\n  \"cmd\": \"echo 'hello'\",\n  \"cpus\": 0.1,\n  \"mem\": 16.0,\n  \"instances\": 1\n}"
  },
  {
    "path": "cli/src/integration-test/resources/clusterconfig/basic.groovy",
    "chars": 618,
    "preview": "package clusterconfig\n\nminimesos {\n\n    mapPortsToHost = true\n    timeout = 60\n    mesosVersion = \"1.0.0\"\n    clusterNam"
  },
  {
    "path": "cli/src/integration-test/resources/clusterconfig/two-agents.groovy",
    "chars": 365,
    "preview": "package clusterconfig\n\nminimesos {\n    agent {\n        resources {\n            cpu {\n                role = \"*\"\n        "
  },
  {
    "path": "cli/src/integration-test/resources/configFiles/complete-minimesosFile",
    "chars": 1415,
    "preview": "minimesos {\n    clusterName = \"Change Cluster Name in minimesosFile file\"\n    mapPortsToHost = false\n    loggingLevel = "
  },
  {
    "path": "cli/src/integration-test/resources/configFiles/invalid-minimesosFile.txt",
    "chars": 7,
    "preview": "invalid"
  },
  {
    "path": "cli/src/integration-test/resources/configFiles/marathonAppConfig-minimesosFile",
    "chars": 1323,
    "preview": "minimesos {\n    clusterName = \"minimesos-test\"\n    mapPortsToHost = false\n    loggingLevel = \"INFO\"\n    mapAgentSandboxV"
  },
  {
    "path": "cli/src/integration-test/resources/configFiles/withMarathon-minimesosFile",
    "chars": 271,
    "preview": "minimesos {\n    clusterName = \"minimesos-test\"\n    mapPortsToHost = false\n    loggingLevel = \"INFO\"\n    mapAgentSandboxV"
  },
  {
    "path": "cli/src/integration-test/resources/logback-test.xml",
    "chars": 390,
    "preview": "<configuration debug=\"false\">\n\n\t<appender name=\"console\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<target>System.o"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/Command.java",
    "chars": 372,
    "preview": "package com.containersol.minimesos.main;\n\npublic interface Command {\n\n    /**\n     * Validates combination of command pa"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandDestroy.java",
    "chars": 1349,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameters;\nimport com.containersol.minimesos.clus"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandHelp.java",
    "chars": 525,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameters;\n\n/**\n * Help command\n */\n@Parameters(s"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandInfo.java",
    "chars": 3758,
    "preview": "package com.containersol.minimesos.main;\n\nimport java.io.PrintStream;\nimport java.net.URI;\nimport java.util.List;\n\nimpor"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandInit.java",
    "chars": 3930,
    "preview": "package com.containersol.minimesos.main;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSyst"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandInstall.java",
    "chars": 4065,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameter;\nimport com.beust.jcommander.Parameters;"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandLogs.java",
    "chars": 5083,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameter;\nimport com.beust.jcommander.Parameters;"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandPs.java",
    "chars": 1933,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameters;\nimport com.containersol.minimesos.clus"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandState.java",
    "chars": 1240,
    "preview": "package com.containersol.minimesos.main;\n\nimport java.io.PrintStream;\n\nimport com.beust.jcommander.Parameters;\nimport co"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandUninstall.java",
    "chars": 2892,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameter;\nimport com.beust.jcommander.Parameters;"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandUp.java",
    "chars": 5384,
    "preview": "package com.containersol.minimesos.main;\n\nimport java.io.InputStream;\nimport java.io.PrintStream;\n\nimport com.beust.jcom"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/CommandVersion.java",
    "chars": 902,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.beust.jcommander.Parameters;\n\nimport java.io.PrintStream;\n\n/**\n * C"
  },
  {
    "path": "cli/src/main/java/com/containersol/minimesos/main/Main.java",
    "chars": 5665,
    "preview": "package com.containersol.minimesos.main;\n\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\nimport java.util.HashM"
  },
  {
    "path": "cli/src/test/java/com/containersol/minimesos/main/CommandInstallTest.java",
    "chars": 2019,
    "preview": "package com.containersol.minimesos.main;\n\nimport com.containersol.minimesos.cluster.ClusterRepository;\nimport com.contai"
  },
  {
    "path": "cli/src/test/java/com/containersol/minimesos/main/MainTest.java",
    "chars": 4577,
    "preview": "package com.containersol.minimesos.main;\n\nimport org.apache.commons.io.output.ByteArrayOutputStream;\nimport org.junit.Be"
  },
  {
    "path": "cli/src/test/resources/app.json",
    "chars": 187,
    "preview": "{\n  \"id\": \"hello\",\n  \"container\": {\n    \"type\": \"MESOS\",\n    \"docker\": {\n      \"image\": \"weaveworks/\",\n      \"network\": "
  },
  {
    "path": "cli/src/test/resources/group.json",
    "chars": 284,
    "preview": "{\n  \"id\": \"pingPongGroup\",\n  \"groups\": [\n    {\n      \"id\": \"ping\",\n      \"cmd\": \"echo 'ping'\",\n      \"cpus\": 0.1,\n      "
  },
  {
    "path": "docs/index.md",
    "chars": 13792,
    "preview": "# minimesos introduction\n\nThe experimentation and testing tool for Apache Mesos. `minimesos` is a tool created for a qui"
  },
  {
    "path": "gradle/quality.gradle",
    "chars": 418,
    "preview": "apply plugin: 'findbugs'\napply plugin: 'checkstyle'\napply plugin: 'pmd'\n\ntasks.withType(FindBugs) {\n  excludeFilter = fi"
  },
  {
    "path": "gradle/spock.gradle",
    "chars": 824,
    "preview": "// used for unit tests\napply plugin: 'groovy'\n\ndef spockVersion = '1.0-groovy-2.4'\ndef powermockVersion = \"1.6.1\"\n\ndepen"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Thu Apr 21 17:15:12 CEST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER"
  },
  {
    "path": "gradle.properties",
    "chars": 178,
    "preview": "org.gradle.jvmargs=-Xmx1024M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\nrelease.useAutomaticVersion = false\nv"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "minimesos/build.gradle",
    "chars": 2334,
    "preview": "apply plugin: \"groovy\"\n\nsourceSets {\n    main {\n        groovy {\n            // this makes the groovy-compiler compile g"
  },
  {
    "path": "minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/AuthenticationTest.java",
    "chars": 1499,
    "preview": "package com.containersol.minimesos.integrationtest;\n\nimport com.containersol.minimesos.cluster.MesosCluster;\nimport com."
  },
  {
    "path": "minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/MesosClusterTest.java",
    "chars": 8205,
    "preview": "package com.containersol.minimesos.integrationtest;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.co"
  },
  {
    "path": "minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/HelloWorldContainer.java",
    "chars": 1445,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\nimport com.containersol.minimesos.config.ContainerConfigB"
  },
  {
    "path": "minimesos/src/integration-test/java/com.containersol.minimesos/integrationtest/container/MesosExecuteContainer.java",
    "chars": 1366,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\nimport com.containersol.minimesos.integrationtest.MesosCl"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/AgentResourcesConfig.groovy",
    "chars": 4670,
    "preview": "package com.containersol.minimesos.config\n\nimport groovy.util.logging.Slf4j\n\nimport java.util.regex.Matcher\n\n@Slf4j\nclas"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/AppConfig.groovy",
    "chars": 343,
    "preview": "package com.containersol.minimesos.config\n\n/**\n * Configuration for a Marathon app. Path is relative to the minimesosFil"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ClusterConfig.groovy",
    "chars": 3897,
    "preview": "package com.containersol.minimesos.config\n\nimport groovy.util.logging.Slf4j\nimport org.apache.commons.lang.StringUtils\n\n"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ConfigParser.groovy",
    "chars": 6320,
    "preview": "package com.containersol.minimesos.config\n\nimport groovy.util.logging.Slf4j\n\nimport java.text.DecimalFormat\nimport java."
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ConsulConfig.groovy",
    "chars": 461,
    "preview": "package com.containersol.minimesos.config;\n\npublic class ConsulConfig extends ContainerConfigBlock implements ContainerC"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ContainerConfig.groovy",
    "chars": 263,
    "preview": "package com.containersol.minimesos.config\n\n/**\n * Common methods for containers' configuration\n */\ninterface ContainerCo"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ContainerConfigBlock.groovy",
    "chars": 342,
    "preview": "package com.containersol.minimesos.config;\n\npublic class ContainerConfigBlock extends GroovyBlock implements ContainerCo"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/GroovyBlock.groovy",
    "chars": 454,
    "preview": "package com.containersol.minimesos.config;\n\n/**\n * Contains a collection of properties for a configuration object.\n */\nc"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/GroupConfig.groovy",
    "chars": 348,
    "preview": "package com.containersol.minimesos.config;\n\n/**\n * Configuration for a Marathon group. Path is relative to the minimesos"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/MarathonConfig.groovy",
    "chars": 1331,
    "preview": "package com.containersol.minimesos.config\n\nimport com.containersol.minimesos.MinimesosException\n\nclass MarathonConfig ex"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/MesosAgentConfig.groovy",
    "chars": 767,
    "preview": "package com.containersol.minimesos.config\n\nimport groovy.util.logging.Slf4j\n\n@Slf4j\nclass MesosAgentConfig extends Mesos"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/MesosContainerConfig.groovy",
    "chars": 771,
    "preview": "package com.containersol.minimesos.config\n\nabstract class MesosContainerConfig extends ContainerConfigBlock implements C"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/MesosDNSConfig.groovy",
    "chars": 382,
    "preview": "package com.containersol.minimesos.config;\n\npublic class MesosDNSConfig extends ContainerConfigBlock implements Containe"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/MesosMasterConfig.groovy",
    "chars": 488,
    "preview": "package com.containersol.minimesos.config\n\nimport groovy.util.logging.Slf4j\n\n@Slf4j\nclass MesosMasterConfig extends Meso"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/RegistratorConfig.groovy",
    "chars": 400,
    "preview": "package com.containersol.minimesos.config;\n\npublic class RegistratorConfig extends ContainerConfigBlock implements Conta"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDef.groovy",
    "chars": 379,
    "preview": "package com.containersol.minimesos.config\n\n/**\n * Check http://mesos.apache.org/documentation/latest/attributes-resource"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDefRanges.groovy",
    "chars": 445,
    "preview": "package com.containersol.minimesos.config\n\n/**\n * Check http://mesos.apache.org/documentation/latest/attributes-resource"
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ResourceDefScalar.groovy",
    "chars": 1579,
    "preview": "package com.containersol.minimesos.config\n\nimport java.text.DecimalFormat\nimport java.text.DecimalFormatSymbols\n\n/**\n * "
  },
  {
    "path": "minimesos/src/main/groovy/com/containersol/minimesos/config/ZooKeeperConfig.groovy",
    "chars": 505,
    "preview": "package com.containersol.minimesos.config\n\npublic class ZooKeeperConfig extends ContainerConfigBlock implements Containe"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/MinimesosException.java",
    "chars": 331,
    "preview": "package com.containersol.minimesos;\n\n/**\n * Thrown when a minimesos command fails.\n */\npublic class MinimesosException e"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterProcess.java",
    "chars": 893,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport java.net.URI;\n\n/**\n * Generic functionality of every cluster member\n"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterRepository.java",
    "chars": 3410,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport com.containersol.minimesos.MinimesosException;\nimport org.apache.com"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/ClusterUtil.java",
    "chars": 1396,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/Consul.java",
    "chars": 128,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Consul functionality\n */\npublic interface Consul extends ClusterProc"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/Filter.java",
    "chars": 1105,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport java.util.function.Predicate;\n\npublic class Filter {\n\n    private Fi"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/Marathon.java",
    "chars": 1289,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport com.mashape.unirest.http.HttpResponse;\nimport com.mashape.unirest.ht"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosAgent.java",
    "chars": 168,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Functionality of Mesos Master\n */\npublic interface MesosAgent extend"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosCluster.java",
    "chars": 16306,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNot"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosClusterFactory.java",
    "chars": 572,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Interface for creating members of the cluster and destroying running"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosContainer.java",
    "chars": 548,
    "preview": "package com.containersol.minimesos.cluster;\n\nimport com.containersol.minimesos.state.State;\nimport com.mashape.unirest.h"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosDns.java",
    "chars": 120,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Mesos DNS\n */\npublic interface MesosDns extends ClusterProcess {\n\n}\n"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/MesosMaster.java",
    "chars": 191,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Functionality of Mesos Master\n */\npublic interface MesosMaster exten"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/Registrator.java",
    "chars": 169,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Consul functionality\n */\npublic interface Registrator extends Cluste"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/cluster/ZooKeeper.java",
    "chars": 256,
    "preview": "package com.containersol.minimesos.cluster;\n\n/**\n * Expected from ZooKeeper functionality\n */\npublic interface ZooKeeper"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/docker/DockerClientFactory.java",
    "chars": 1058,
    "preview": "package com.containersol.minimesos.docker;\n\nimport com.github.dockerjava.api.DockerClient;\nimport com.github.dockerjava."
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/docker/DockerContainersUtil.java",
    "chars": 7798,
    "preview": "package com.containersol.minimesos.docker;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/integrationtest/container/AbstractContainer.java",
    "chars": 9129,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\n"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/integrationtest/container/ContainerName.java",
    "chars": 3094,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\n/**\n * Utility class to assist container naming conventio"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/junit/MesosClusterTestRule.java",
    "chars": 3296,
    "preview": "package com.containersol.minimesos.junit;\n\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport "
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/marathon/MarathonContainer.java",
    "chars": 13502,
    "preview": "package com.containersol.minimesos.marathon;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.container"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/ClusterContainers.java",
    "chars": 2162,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.cluster.ClusterProcess;\n\nimport java.util.A"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/ConsulContainer.java",
    "chars": 3172,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/MesosAgentContainer.java",
    "chars": 5375,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/MesosClusterContainersFactory.java",
    "chars": 10450,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.In"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/MesosContainerImpl.java",
    "chars": 3833,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/MesosDnsContainer.java",
    "chars": 2724,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.cluster.MesosCluster;\nimport com.containers"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/MesosMasterContainer.java",
    "chars": 6293,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/RegistratorContainer.java",
    "chars": 2101,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.cluster.Consul;\nimport com.containersol.min"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/mesos/ZooKeeperContainer.java",
    "chars": 3569,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.containersol"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Discovery.java",
    "chars": 421,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Maps Me"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Executor.java",
    "chars": 508,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n@JsonIgnorePro"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Framework.java",
    "chars": 2013,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fast"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Port.java",
    "chars": 591,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Maps Me"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Ports.java",
    "chars": 452,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\nimport java.ut"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/State.java",
    "chars": 1931,
    "preview": "package com.containersol.minimesos.state;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Hash"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/state/Task.java",
    "chars": 1632,
    "preview": "package com.containersol.minimesos.state;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fast"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/CollectionsUtils.java",
    "chars": 2381,
    "preview": "package com.containersol.minimesos.util;\n\nimport com.containersol.minimesos.MinimesosException;\n\nimport java.util.ArrayL"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/Downloader.java",
    "chars": 970,
    "preview": "package com.containersol.minimesos.util;\n\nimport com.containersol.minimesos.MinimesosException;\nimport com.mashape.unire"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/Environment.java",
    "chars": 741,
    "preview": "package com.containersol.minimesos.util;\n\n/**\n * Utility for detecting the runtime environment.\n */\npublic class Environ"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/EnvironmentBuilder.java",
    "chars": 860,
    "preview": "package com.containersol.minimesos.util;\n\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * Provides convenient AP"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/Predicate.java",
    "chars": 98,
    "preview": "package com.containersol.minimesos.util;\n\npublic interface Predicate<T> {\n    boolean test(T t);\n}"
  },
  {
    "path": "minimesos/src/main/java/com/containersol/minimesos/util/ResourceUtil.java",
    "chars": 1841,
    "preview": "package com.containersol.minimesos.util;\n\nimport com.containersol.minimesos.MinimesosException;\n\nimport java.util.ArrayL"
  },
  {
    "path": "minimesos/src/main/resources/logback.xml",
    "chars": 620,
    "preview": "<configuration debug=\"false\">\n\n\t<appender name=\"JAVA\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<target>System.out<"
  },
  {
    "path": "minimesos/src/main/resources/marathon/elasticsearch.json",
    "chars": 345,
    "preview": "{\n  \"id\": \"elasticsearch-mesos-scheduler\",\n  \"container\": {\n\t\"docker\": {\n\t  \"image\": \"mesos/elasticsearch-scheduler\",\n\t "
  },
  {
    "path": "minimesos/src/main/resources/marathon/mesos-consul.json",
    "chars": 306,
    "preview": "{\n  \"args\": [\n\t\"--zk={{MINIMESOS_ZOOKEEPER}}\",\n\t\"--consul=1\",\n\t\"--consul-ip={{MINIMESOS_CONSUL_IP}}\"\n  ],\n  \"container\":"
  },
  {
    "path": "minimesos/src/test/groovy/com/containersol/minimesos/config/AgentResourcesConfigTest.groovy",
    "chars": 2451,
    "preview": "package com.containersol.minimesos.config\n\nimport org.junit.Test\n\nimport static org.junit.Assert.assertEquals;\n\npublic c"
  },
  {
    "path": "minimesos/src/test/groovy/com/containersol/minimesos/config/ConfigParserTest.groovy",
    "chars": 11319,
    "preview": "package com.containersol.minimesos.config\n\nimport com.containersol.minimesos.MinimesosException\nimport org.junit.Before\n"
  },
  {
    "path": "minimesos/src/test/groovy/com/containersol/minimesos/config/ConfigWriterTest.groovy",
    "chars": 3389,
    "preview": "package com.containersol.minimesos.config\n\nimport org.junit.Before\nimport org.junit.Test\n\nimport static org.junit.Assert"
  },
  {
    "path": "minimesos/src/test/groovy/com/containersol/minimesos/config/ResourceDefScalarTest.groovy",
    "chars": 547,
    "preview": "package com.containersol.minimesos.config\n\nimport org.junit.Test\n\nimport static org.junit.Assert.assertEquals;\n\npublic c"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/ClusterBuilderTest.java",
    "chars": 2891,
    "preview": "package com.containersol.minimesos;\n\nimport com.containersol.minimesos.cluster.MesosCluster;\nimport com.containersol.min"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/ParseStateJSONTest.java",
    "chars": 11620,
    "preview": "package com.containersol.minimesos;\n\nimport com.containersol.minimesos.state.Framework;\nimport com.containersol.minimeso"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/factory/MesosClusterContainersFactoryTest.java",
    "chars": 838,
    "preview": "package com.containersol.minimesos.factory;\n\nimport com.containersol.minimesos.cluster.MesosCluster;\nimport com.containe"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/integrationtest/container/ContainerNameTest.java",
    "chars": 2579,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\nimport com.containersol.minimesos.cluster.MesosCluster;\ni"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/integrationtest/container/MesosAgentTest.java",
    "chars": 1502,
    "preview": "package com.containersol.minimesos.integrationtest.container;\n\nimport com.containersol.minimesos.MinimesosException;\nimp"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/jdepend/JDependCyclesTest.java",
    "chars": 1148,
    "preview": "package com.containersol.minimesos.jdepend;\n\nimport jdepend.framework.JDepend;\nimport org.junit.Before;\nimport org.junit"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/mesos/ClusterContainersTest.java",
    "chars": 2030,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.cluster.ClusterProcess;\nimport com.containe"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/mesos/ClusterUtilTest.java",
    "chars": 2605,
    "preview": "package com.containersol.minimesos.mesos;\n\nimport com.containersol.minimesos.cluster.ClusterProcess;\nimport com.containe"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/util/CollectionsUtilsTest.java",
    "chars": 1203,
    "preview": "package com.containersol.minimesos.util;\n\nimport com.containersol.minimesos.MinimesosException;\n\nimport org.junit.Test;\n"
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/util/EnvironmentBuilderTest.java",
    "chars": 1190,
    "preview": "package com.containersol.minimesos.util;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\nimport java.util.Map;\nimport "
  },
  {
    "path": "minimesos/src/test/java/com/containersol/minimesos/util/ResourceUtilTest.java",
    "chars": 1378,
    "preview": "package com.containersol.minimesos.util;\n\nimport com.containersol.minimesos.MinimesosException;\nimport org.junit.Test;\n\n"
  },
  {
    "path": "minimesos/src/test/resources/configFiles/minimesosFile-authenticationTest",
    "chars": 1380,
    "preview": "minimesos {\n    clusterName = \"authentication-test\"\n    mapPortsToHost = false\n    loggingLevel = \"INFO\"\n    mapAgentSan"
  },
  {
    "path": "minimesos/src/test/resources/configFiles/minimesosFile-mesosClusterTest",
    "chars": 2328,
    "preview": "minimesos {\n    clusterName = \"mesos-cluster-test\"\n    mapPortsToHost = true\n    loggingLevel = \"INFO\"\n    mapAgentSandb"
  },
  {
    "path": "minimesos/src/test/resources/logback-test.xml",
    "chars": 390,
    "preview": "<configuration debug=\"false\">\n\n\t<appender name=\"console\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<target>System.o"
  },
  {
    "path": "opt/apps/weave-scope.json",
    "chars": 742,
    "preview": "{\n  \"id\": \"weave-scope\",\n  \"cpus\": 1,\n  \"mem\": 128,\n  \"instances\": 1,\n  \"constraints\": [\n    [\n      \"hostname\",\n      \""
  },
  {
    "path": "opt/sonar/DockerFile",
    "chars": 407,
    "preview": "FROM sonarqube:5.3\nMAINTAINER Container Solutions BV <info@container-solutions.com>\n\nADD sonar-plugins/sonar-github-plug"
  },
  {
    "path": "opt/sonar/certificate.yaml",
    "chars": 205,
    "preview": "apiVersion: extensions/v1beta1\nkind: ThirdPartyResource\ndescription: \"A specification of a Let's Encrypt Certificate to "
  },
  {
    "path": "opt/sonar/setup.md",
    "chars": 1365,
    "preview": "### Create Persistent Disk\n`gcloud compute disks create --size 200GB minimesos-sonar-postgres-disk`\n\n### Attach created "
  },
  {
    "path": "opt/sonar/sonar-deployment.yaml",
    "chars": 687,
    "preview": "apiVersion: extensions/v1beta1\nkind: Deployment\nmetadata:\n  name: sonar\nspec:\n  replicas: 1\n  template:\n    metadata:\n  "
  },
  {
    "path": "opt/sonar/sonar-postgres-deployment.yaml",
    "chars": 962,
    "preview": "apiVersion: extensions/v1beta1\nkind: Deployment\nmetadata:\n  name: sonar-postgres\nspec:\n  replicas: 1\n  template:\n    met"
  },
  {
    "path": "opt/sonar/sonar-postgres-service.yaml",
    "chars": 166,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    name: sonar-postgres\n  name: sonar-postgres\nspec:\n  ports:\n    - po"
  },
  {
    "path": "opt/sonar/sonar-service.yaml",
    "chars": 203,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    name: sonar\n  name: sonar\nspec:\n  ports:\n    - port: 80\n      targe"
  },
  {
    "path": "opt/vagrant/debian/jessie64/Vagrantfile",
    "chars": 271,
    "preview": "Vagrant.configure(2) do |config|\n\n  config.vm.box = \"debian/contrib-jessie64\"\n\n  config.vm.provider \"virtualbox\" do |vb|"
  },
  {
    "path": "opt/vagrant/debian/jessie64/provision.sh",
    "chars": 1314,
    "preview": "#!/usr/bin/env bash\n\n###\n###  JDK and Gradle\n###\n\necho \"deb http://ftp.debian.org/debian jessie-backports main\" > /etc/a"
  },
  {
    "path": "settings.gradle",
    "chars": 73,
    "preview": "rootProject.name = 'minimesos-project'\ninclude \"minimesos\"\ninclude \"cli\"\n"
  },
  {
    "path": "travis.sh",
    "chars": 1244,
    "preview": "#!/bin/bash\nset -ev\n\nGH_SONARQ_PARAMS=\"\"\n\n# When run on Travis CI, env var TRAVIS_PULL_REQUEST either contains PR number"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the ContainerSolutions/mini-mesos GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 155 files (335.0 KB), approximately 83.9k tokens, and a symbol index with 589 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!