Giter Club home page Giter Club logo

mantl-api's Introduction

Mantl API

Build Status

An API interface to Mantl.

Currently, Mantl API allows you to install and uninstall DCOS packages on Mantl. More capabilities are planned for the future.

Table of Contents

Mantl API on Mantl Clusters

As of the 0.5 release, Mantl API is installed by default on Mantl clusters. It is deployed via Marathon and will be running on one of the worker nodes. Mantl automatically discovers the Mantl API instance and puts it behind Nginx on all control nodes at the /api endpoint. By default, it is secured with SSL and basic authentication. As an example, on a default Mantl install, you can retrieve the list of available packages by running a command like the following:

curl -k -u admin:mantlpw https://mantl-control-01/api/1/packages

You just need to update the command with the correct host name and credentials for your cluster. All of the examples in this document will assume you are working with Mantl API on a Mantl cluster and will use urls underneath /api.

Building

docker build -t mantl-api .

Deploying Manually

You can run Mantl API on your cluster via Marathon. An example mantl-api.json is included below:

{
  "id": "/mantl-api",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "ciscocloud/mantl-api:0.1.0",
      "network": "BRIDGE",
      "portMappings": [
        { "containerPort": 4001, "hostPort": 0 }
      ]
    }
  },
  "instances": 1,
  "cpus": 1.0,
  "mem": 512,
  "constraints": [["hostname", "UNIQUE"]],
  "env": {
    "CONSUL_HTTP_SSL_VERIFY": "false",
    "MANTL_API_LOG_LEVEL": "debug",
    "MANTL_API_CONSUL": "https://consul.service.consul:8500",
    "MANTL_API_MESOS_PRINCIPAL": "mantl-api",
    "MANTL_API_MESOS_SECRET": "secret"
  },
  "healthChecks": [
    {
      "protocol": "HTTP",
      "path": "/health",
      "gracePeriodSeconds": 3,
      "intervalSeconds": 10,
      "portIndex": 0,
      "timeoutSeconds": 10,
      "maxConsecutiveFailures": 3
    }
  ]
}

You will need to replace the MANTL_API_MESOS_PRINCIPAL and MANTL_API_MESOS_SECRET variables with valid Mesos credentials. These can be found in the security.yml file that was generated when you ran security-setup for your Mantl cluster.

All Mantl API configuration can be set with environment variables. See below for the additional configuration options that are available.

To install Mantl API, you can submit the above json to Marathon.

curl -k -u admin:mantlpw -X POST -d @mantl-api.json -H "Content-type: application/json" https://mantl-control-01/marathon/v2/apps

You will need to replace admin:mantlpw with valid Marathon credentials (see marathon_http_credentials in your security.yml). You will also replace mantl-control-01 with the host of one your Mantl control nodes.

After a few moments, Mantl API should be running on your cluster.

Usage with Vault

When configured with either vault-token or vault-cubbyhole-token, mantl-api will contact Vault to retrieve its secrets. They should be stored at secret/mantl-api. mantl-api will look for the following keys within that secret's Data field: mesos-principal, mesos-secret, marathon-user, and marathon-password. You don't have to store all of your secrets in Vault to take advantage of this feature, mantl-api will only use the ones that are present.

Options

Configuration options:

--config-file string             The path to a (optional) configuration file
--consul string                  Consul API address (default "http://localhost:8500")
--consul-acl-token string        Consul ACL token for accessing mantl-install/apps path
--consul-no-verify-ssl           Disable Consul SSL verification
--consul-refresh-interval int    The number of seconds after which to check consul for package requests (default 10)
--force-sync                     Force a synchronization of respository all sources at startup
--listen string                  listen for connections on this address (default ":4001")
--log-format string              specify output (text or json) (default "text")
--log-level string               one of debug, info, warn, error, or fatal (default "info")
--marathon string                Marathon API address
--marathon-no-verify-ssl         Disable Marathon SSL verification
--marathon-password string       Marathon API password
--marathon-user string           Marathon API user
--mesos string                   Mesos API address
--mesos-no-verify-ssl            Disable Mesos SSL verification
--mesos-principal string         Mesos principal for framework authentication
--mesos-secret string            Deprecated. Use mesos-secret-path instead
--mesos-secret-path string       Path to a file on host sytem that contains the mesos secret for framework authentication (default "/etc/sysconfig/mantl-api")
--vault-cubbyhole-token string   token for retrieving token from vault
--vault-token string             token for retrieving secrets from vault
--zookeeper string               Comma-delimited list of zookeeper servers

Every option can be set via environment variables prefixed with MANTL_API. For example, you can use MANTL_API_LOG_LEVEL for log-level, MANTL_API_CONSUL for consul, and so on. You can also specify all configuration from a TOML configuration file using the config-file argument.

Package Repository

Mantl API depends on a repository of package definitions stored in the Consul KV store. mantl-universe is the authoritative repository of packages that work out-of-the-box on Mantl today. You can install any of the DCOS packages but you will likely have to customize some of the configuration to work on Mantl. Most of the Mesosphere packages assume that service discovery is provided by Mesos-DNS and need to be converted to work with the Consul DNS interface.

Tree Structure

Mantl API is compatible with the package repository structure created for Mesosphere DCOS packages. Each repository contains a directory structure that looks something like this:

repo/packages
├── C
│   ├── cassandra
│   │   ├── 0
│   │   │   ├── config.json
│   │   │   ├── marathon.json
│   │   │   └── package.json
│   │   ├── 1
│   │   │   ├── command.json
│   │   │   ├── config.json
│   │   │   ├── marathon.json
│   │   │   └── package.json
├── H
│   └── hdfs
│       ├── 0
│       │   ├── command.json
│       │   ├── config.json
│       │   ├── marathon.json
│       │   └── package.json
│       ├── 1
│       │   ├── command.json
│       │   ├── config.json
│       │   ├── marathon.json
│       │   └── package.json
|__ ...

For each named package (cassandra and hdfs in the example above), there is a directory of JSON files corresponding to each version.

Multiple Repositories

Mantl API supports the ability to layer repositories. By default, Mantl API is configured with Mantl Universe as the base repository. It is possible to layer additional repositories on top.

The order of the repositories is important. By default, Mantl Universe is configured with index 0. In the Consul KV store, the repositories are stored as follows:

Name Consul KV Path
Mantl Universe mantl-install/repository/0
Custom Repository mantl-install/repository/1

Repositories with higher indexes are prioritized. When Mantl API receives a request to install a particular package, it will use the package definition found in the repository with the highest index. If there are any required files missing, it will look for the corresponding package version in repositories with the lower indexes until it is able to construct a valid, installable package. For example, if mantl-install/repository/1/repo/packages/H/hdfs/1 (Custom Repository) exists but does not have a config.json file, Mantl API will merge in the config.json file from mantl-install/repository/0/repo/packages/H/hdfs/1 (Mantl Universe). This enables the ability to make small package customizations rather than creating an entirely new version of a package.

Configuring Sources

If you want to use additional or different source repositories, you can specify a configuration file that contains your source definitions using the --config-file argument. Here is an example configuration file that uses 2 sources — one named "mesosphere" from a git repository and the other named "mantl-universe" from the local file system:

[sources]

[sources.mesosphere]
path = "https://github.com/mesosphere/universe.git"
type = "git"
index = 0

[sources.mantl]
path = "/home/ryan/Projects/mantl-universe"
index = 1

The following attributes can be specified for each source:

  • path
  • type — git or filesystem (default)
  • index
  • branch — only applicable for the git type

Synchronizing Repository Sources

The package repositories are synchronized to the Consul K/V backend. If you want to refresh your repositories, you can run the following command:

mantl-api sync --consul http://consul.service.consul:8500

Packages

The goals of the packaging system are:

  1. Make it easy to contribute packages to Mantl
  2. Rely on the existing DCOS package structure when possible
  3. Immutable package versions
  4. Ability for users to build customized package versions

Structure

Mantl Universe packages are based on the DCOS packaging format from Mesosphere. Packages in Mantl Universe are intended to be installed with Mantl API and may depend on the corresponding package version in the Mesosphere Universe.

Each package is made up of several json files:

package.json

The package.json file is where package metadata is set. This includes things like the name, version, description, and maintainer of the package.

config.json

The config.json file contains the configuration schema and defaults for the package.

mantl.json

The mantl.json overrides configuration defaults from the config.json file (either directly in the package or from the config.json for the corresponding package version in the Mesosphere universe) with values that are known to work on Mantl.

Also, the presence of the mantl.json dictates whether the package is "supported" on Mantl. It can be empty {} if there is no specific changes required to make the package run on Mantl.

mantl.json includes a setting that allows you to control how the application is load balanced on Mantl clusters. Currently, it is a simple toggle that allows you to control whether the application will be load balanced by Traefik in a Mantl cluster. Here is an example mantl.json with no other settings other than the load balancing configuration:

{
  "mantl": {
    "load-balancer": "external|off"
  }
}

If mantl.load-balancer is set to "external", the application will be included in the Traefik load balancer. Any other value will disable load balancing.

marathon.json

The marathon.json file contains the Marathon application json for the package. It is a mustache template that is rendered using data from config.json and mantl.json.

uninstall.json

The uninstall.json defines additional behavior when uninstalling a package. The uninstall support is currently limited to removing zookeeper nodes. It is also a mustache template so that variables from config.json and mantl.json can be used in the uninstall definition.

{
  "zookeeper": {
    "delete": [
      {
        "path": "{{kafka.storage}}",
        "always": true
      }
    ]
  }
}

Example uninstall.json that deletes zookeeper nodes with a path based on the kafka.storage variable.

Developing Packages

When developing packages, it is easiest to run Mantl API locally and point it to a Mantl cluster. Using a Vagrant Mantl cluster is the simplest and fastest as pointing Mantl API to a remote cluster can be complicated by security settings. However, here is an example configuration file (config.toml) showing how to run Mantl API locally against a remote Mantl cluster.

consul = "https://control-node:8500"
consul-no-verify-ssl = true
marathon = "https://control-node/marathon"
marathon-user = "user"
marathon-password = "password"
marathon-no-verify-ssl = true
mesos-principal = "mesos-principal"
mesos-secret = "mesos-secret"
mesos = "http://control-node:15050"
mesos-no-verify-ssl = true
zookeeper = "control-node:2181"

# global
log-level = "debug"

[sources]

[sources.mantl]
path = "/Users/ryan/Projects/mantl-universe"
index = 0

You will need to update the URLs and credentials as appropriate for your cluster.

Finally, you will need to update firewalls and security groups so that your development machine has access to the above ports.

You can then run Mantl API with a command like the following:

./bin/mantl-api --config-file config.toml

As shown above, you should have a copy of a valid repository on your local file system. The easiest thing to do is clone or fork Mantl. Create or update your package in this local repository. When you want to test it, you first need to synchronize it to the Mantl cluster. You can run a command like the following to synchronize the repository:

./bin/mantl-api --config-file config.toml sync

Then, you should be able to install your package using normal Mantl API calls. For example:

curl -X POST -d "{\"name\": \"mycustompackage\"}" http://localhost:4001/api/1/install

Usage

The following example curl commands assume a default Mantl API installation (with a control node called mantl-control-01) on a Mantl cluster with SSL and authentication turned off. You will need to adjust the commands to work with valid URLs and credentials for your cluster.

Installing a Package

It is a single API call to install a package. In the example below, we are going to run Cassandra on our Mantl cluster.

curl -X POST -d "{\"name\": \"cassandra\"}" http://mantl-control-01/api/1/install

You can use the Marathon API or UI to find this. You'll also need to make sure that the port is accessible to the machine where you are calling the API from. Adjust the security groups or firewall rules for your platform accordingly.

After about 5 minutes, you should have Cassandra up and running on your Mantl cluster.

Uninstalling a Package

Uninstalling is just as easy. Run the command below to uninstall Cassandra:

curl -X DELETE -d "{\"name\": \"cassandra\"}" http://mantl-control-01/api/1/install

After a moment, Cassandra will have been removed from your cluster. This will also remove the Zookeeper state for the Cassandra framework. In the future, we will add more flexibility in being able to control what is uninstalled.

API Reference

Endpoints

Endpoint Method Description
/health GET health check - returns OK with an HTTP 200 status
/1/packages GET list available packages
/1/packages/:name GET provides information about a specific package
/1/install POST install a package
/1/install DELETE uninstalls a specific package
/1/frameworks GET lists mesos frameworks
/1/frameworks/:id DELETE shuts down a running mesos framework

GET /health

GET /health: returns OK

curl http://mantl-control-01/api/health
OK

GET /1/packages

GET /1/packages: returns a JSON representation of packages available to install.

curl http://mantl-control-01/api/1/packages | jq .
[
  {
    "name": "cassandra",
    "description": "Apache Cassandra running on Apache Mesos",
    "framework": true,
    "currentVersion": "0.2.0-1",
    "supported": true,
    "tags": [
      "mesosphere",
      "framework",
      "data",
      "database"
    ],
    "versions": {
      "0.1.0-1": {
        "version": "0.1.0-1",
        "index": "0",
        "supported": true
      },
      "0.2.0-1": {
        "version": "0.2.0-1",
        "index": "1",
        "supported": true
      }
    }
  },
  ...
  {
    "name": "swarm",
    "description": "Swarm is a Docker-native clustering system.",
    "framework": true,
    "currentVersion": "0.4.0",
    "supported": false,
    "tags": [
      "mesosphere",
      "framework",
      "docker"
    ],
    "versions": {
      "0.4.0": {
        "version": "0.4.0",
        "index": "0",
        "supported": false
      }
    }
  }
]

GET /1/packages/

GET /1/packages/<package>: returns a JSON representation of a package.

curl http://mantl-control-01/api/1/packages/cassandra | jq .
{
  "name": "cassandra",
  "description": "Apache Cassandra running on Apache Mesos",
  "framework": true,
  "currentVersion": "0.2.0-1",
  "supported": true,
  "tags": [
    "mesosphere",
    "framework",
    "data",
    "database"
  ],
  "versions": {
    "0.1.0-1": {
      "version": "0.1.0-1",
      "index": "0",
      "supported": true
    },
    "0.2.0-1": {
      "version": "0.2.0-1",
      "index": "1",
      "supported": true
    }
  }
}

POST /1/install

POST /1/install: post a JSON representation of a package to install.

curl -X POST -d "{\"name\": \"cassandra\"}" http://mantl-control-01/api/1/install | jq .
{
  "id": "/cassandra/dcos-test",
  "cmd": "$(pwd)/jre*/bin/java $JAVA_OPTS -classpath cassandra-mesos-framework.jar io.mesosphere.mesos.frameworks.cassandra.framework.Main",
  "args": null,
  "user": null,
  "env": {
    "CASSANDRA_ZK_TIMEOUT_MS": "10000",
    "JAVA_OPTS": "-Xms256m -Xmx256m",
    "MESOS_AUTHENTICATE": "true",
    "CASSANDRA_RESOURCE_CPU_CORES": "0.1",
    "CASSANDRA_FAILOVER_TIMEOUT_SECONDS": "604800",
    "DEFAULT_SECRET": "secret",
    "CASSANDRA_BOOTSTRAP_GRACE_TIME_SECONDS": "120",
    "CASSANDRA_DEFAULT_DC": "DC1",
    "CASSANDRA_RESOURCE_MEM_MB": "768",
    "MESOS_ZK": "zk://zookeeper.service.consul:2181/mesos",
    "CASSANDRA_DATA_DIRECTORY": ".",
    "DEFAULT_PRINCIPAL": "mantl-install",
    "CASSANDRA_FRAMEWORK_MESOS_ROLE": "*",
    "CASSANDRA_CLUSTER_NAME": "dcos-test",
    "CASSANDRA_RESOURCE_DISK_MB": "16",
    "CASSANDRA_SEED_COUNT": "2",
    "CASSANDRA_ZK": "zk://zookeeper.service.consul:2181/cassandra-mesos/dcos-test",
    "CASSANDRA_NODE_COUNT": "3",
    "CASSANDRA_DEFAULT_RACK": "RAC1",
    "CASSANDRA_HEALTH_CHECK_INTERVAL_SECONDS": "60"
  },
  "instances": 1,
  "cpus": 0.5,
  "mem": 512,
  "disk": 0,
  "executor": "",
  "constraints": [],
  "uris": [
    "https://downloads.mesosphere.io/cassandra-mesos/artifacts/0.2.0-1/cassandra-mesos-0.2.0-1.tar.gz",
    "https://downloads.mesosphere.io/java/jre-7u76-linux-x64.tar.gz"
  ],
  "storeUrls": [],
  "ports": [
    0
  ],
  "requirePorts": false,
  "backoffFactor": 0,
  "container": null,
  "healthChecks": [
    {
      "path": "/health/cluster",
      "protocol": "HTTP",
      "portIndex": 0,
      "command": null,
      "gracePeriodSeconds": 120,
      "intervalSeconds": 15,
      "timeoutSeconds": 5,
      "maxConsecutiveFailures": 0,
      "ignoreHttp1xx": false
    },
    {
      "path": "/health/process",
      "protocol": "HTTP",
      "portIndex": 0,
      "command": null,
      "gracePeriodSeconds": 120,
      "intervalSeconds": 30,
      "timeoutSeconds": 5,
      "maxConsecutiveFailures": 3,
      "ignoreHttp1xx": false
    }
  ],
  "dependencies": [],
  "upgradeStrategy": {
    "minimumHealthCapacity": 0,
    "maximumOverCapacity": 0
  },
  "labels": {
    "MANTL_PACKAGE_NAME": "cassandra",
    "MANTL_PACKAGE_IS_FRAMEWORK": "true",
    "DCOS_PACKAGE_FRAMEWORK_NAME": "cassandra.dcos-test",
    "MANTL_PACKAGE_FRAMEWORK_NAME": "cassandra.dcos-test",
    "MANTL_PACKAGE_INDEX": "1",
    "MANTL_PACKAGE_VERSION": "0.2.0-1"
  },
  "acceptedResourceRoles": null,
  "version": "2015-09-17T22:19:24.576Z",
  "tasks": [],
  "deployments": [
    {
      "id": "dd113528-388c-4438-a524-9eba45aa2908"
    }
  ],
  "tasksStaged": 0,
  "tasksRunning": 0,
  "tasksHealthy": 0,
  "tasksUnhealthy": 0,
  "backoffSeconds": 0,
  "maxLaunchDelaySeconds": 3600
}

DELETE /1/install

DELETE /1/install: post a JSON representation of package specific uninstall options.

curl -X DELETE -d "{\"name\": \"cassandra\"}" http://mantl-control-01/api/1/install

GET /1/frameworks

GET /1/frameworks: returns a JSON representation of mesos frameworks.

Append a query string of ?completed to list completed frameworks.

curl -s http://mantl-control-01/api/1/frameworks
[
  {
    "name": "elasticsearch",
    "id": "e8569827-307e-416c-8186-47e3d08555b2-0001",
    "active": true,
    "hostname": "mi-worker-001.novalocal",
    "user": "root",
    "registeredTime": "2016-01-30T17:30:44-05:00",
    "reregisteredTime": "0001-01-01T00:00:00Z",
    "activeTasks": 1
  },
  {
    "name": "chronos",
    "id": "8e1863a6-3664-4f93-9f13-44a187a7fca8-0000",
    "active": true,
    "hostname": "mi-control-01.novalocal",
    "user": "root",
    "registeredTime": "2016-01-30T13:57:25-05:00",
    "reregisteredTime": "0001-01-01T00:00:00Z",
    "activeTasks": 0
  },
  {
    "name": "marathon",
    "id": "90e1b7ed-9369-4ec8-b50c-331a47e28468-0000",
    "active": true,
    "hostname": "mi-control-01.node.consul",
    "user": "root",
    "registeredTime": "2016-01-30T13:57:24-05:00",
    "reregisteredTime": "2016-01-31T23:39:52-05:00",
    "activeTasks": 7
  }
]

DELETE /1/frameworks/:id

DELETE /1/frameworks/<mesos-framework-id>: Shutdown the mesos framework with the specified ID.

curl -X DELETE http://mantl-control-01/api/1/frameworks/a1c0c9da-f554-4140-8e04-bb92ac9d2a39-0000

Comparison to Other Software

Mantl API takes advantage of the Mesosphere DCOS packaging format and provides capabilities similar to the package command in the DCOS CLI. The goal is to provide a simple, API-driven way to install and uninstall pre-built packages on Mantl clusters. In the future, mantl-api will contain additional functionality for maintaining and operating Mantl clusters.

Future Enhancement Ideas

  1. Discover running packages (in progress) so that they can automatically be added to UI when applicable.
  2. Operational tasks. Ability to see and manage Mesos frameworks, Marathon tasks, health checks, logs, etc.
  3. Addons / Optional components. Turn on and off optional components.
  4. Cluster management. Scale cluster up and down.
  5. Other ideas?

License

mantl-api is released under the Apache 2.0 license (see LICENSE)

mantl-api's People

Contributors

brianhicks avatar langston-barrett avatar ryane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mantl-api's Issues

cassandra installation fails

I am trying to run cassandra on Marathon using mantl-api.
When I run this command, I dont get any error messages and the Marathon UI always shows "waiting" status for Cassandra app -
curl --insecure -X POST -u admin -d "{"name": "cassandra"}" https://192.168.100.101/api/1/install

Can I get handle to the .json file which is being used for installation on Marathon?
That might give some visibility.
What's the best method to debug such kind of issues in mantl-api?

additional uninstall options

some frameworks and applications leave data behind on the hosts. We should (optionally) support removing this when frameworks are removed.

  • hdfs
  • kafka
  • cassandra
  • probably others

sometimes fails to remove frameworks

Intermittently, mantl-api fails to remove a framework during an uninstall. You may see an error like this:

time="2016-06-07T14:09:40Z" level=debug msg="GET http://lb0-control-02:15050/master/state.json" 
time="2016-06-07T14:09:40Z" level=debug msg="Framework mantl/elasticsearch not active" 

but, the framework is active.

Framework API Does Not Retreive Active Frameworks

When cleaning up a Cassandra un-install, the framework ID in Mesos is required.

But, using the Mantl-API, an empty JSON is returned, though I can see four active frameworks in the Mesos UI.

curl -sku username:password https://<my-mantl-control-01/api/1/frameworks

Further, when copying the Active Framework ID manually out of the Mesos UI and attempting to delete the framework using that ID via the API, this fails as the framework corresponding to the ID is reported as 'not found'.

curl -X DELETE -sku username:password https://<my-mantl-control-01/api/1/frameworks/{My_Framework_ID}
Cloud not shutdown framework {ID}: 400 No framework found with specified ID

Is this a real issue, or user error in some way?

I'm running Mantl 1.1.0 on Openstack.

mantl-api error

This happens whenever i run mantl-api docker container after i provide force-sync option from marathon via environment variable. When mantl-api is first deployed, everything works but after force-sync i have not gotten it to work.

curl -k -u admin:xxx https://xxx/api/1/packages
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

here are the logs from mesos:

time="2016-04-25T04:51:34Z" level=debug msg="GET /1/packages" 
2016/04/25 04:51:35 http: panic serving xxx.xxx.xxx.xx:xxx: interface conversion: interface is nil, not bool
goroutine 28 [running]:
net/http.(*conn).serve.func1(0xc820134c60, 0x7f5eaca5c0e8, 0xc82011e810)
    /usr/lib/go/src/net/http/server.go:1287 +0xb5
github.com/CiscoCloud/mantl-api/install.packageCatalog.packagesIndex(0xc8203a0b40, 0xc82011e060, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/catalog.go:82 +0x631
github.com/CiscoCloud/mantl-api/install.(*Install).getPackages(0xc8201c6c30, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/package.go:324 +0xb2
github.com/CiscoCloud/mantl-api/install.(*Install).Packages(0xc8201c6c30, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/install.go:58 +0x3e
github.com/CiscoCloud/mantl-api/api.(*Api).packages(0xc8203a04e0, 0x7f5eaca65048, 0xc820134d10, 0xc8203ac380, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:90 +0x86
github.com/CiscoCloud/mantl-api/api.(*Api).(github.com/CiscoCloud/mantl-api/api.packages)-fm(0x7f5eaca65048, 0xc820134d10, 0xc8203ac380, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:68 +0x5c
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0xc82037fe80, 0x7f5eaca65048, 0xc820134d10, 0xc8203ac380)
    /go/src/github.com/julienschmidt/httprouter/router.go:344 +0x195
github.com/CiscoCloud/mantl-api/api.logHandler.func1(0x7f5eaca65048, 0xc820134d10, 0xc8203ac380)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:46 +0x1a4
net/http.HandlerFunc.ServeHTTP(0xc820326980, 0x7f5eaca65048, 0xc820134d10, 0xc8203ac380)
    /usr/lib/go/src/net/http/server.go:1422 +0x3a
net/http.serverHandler.ServeHTTP(0xc8202d3e60, 0x7f5eaca65048, 0xc820134d10, 0xc8203ac380)
    /usr/lib/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc820134c60)
    /usr/lib/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
    /usr/lib/go/src/net/http/server.go:1910 +0x3f6

hdfs fail to launch after mantl-api DELETE & POST

hi,
I am running a mantl cluster with 5 workers on AWS.
I managed to launch HDFS using mantl-api with the below mesas-site.xml and I can see that the marathon health checks pass.

when I call mantl-api DELETE to remove the HDFS cluster, it seams that every thing is removed and deleted.

the issue is when I call mantl-api POST again to relaunch the HDFS, the marathon task stuck in "deploying" state. and the HDFS is not working properly.

Thanks
Itay

here is my mesas-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  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. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
  <property>
    <name>mesos.hdfs.data.dir</name>
    <description>The primary data directory in HDFS</description>
    <value>/var/lib/hdfs/data</value>
  </property>

  <!-- Uncomment this to enable secondary data dir
  <property>
    <name>mesos.hdfs.secondary.data.dir</name>
    <description>The secondary data directory in HDFS</description>
    <value>/var/lib/hdfs/data2</value>
  </property>
  -->

  <property>
    <name>mesos.hdfs.domain.socket.dir</name>
    <description>The location used for a local socket used by the data nodes</description>
    <value>/var/run/hadoop-hdfs</value>
  </property>

  <!-- Uncomment this to enable backup
  <property>
    <name>mesos.hdfs.backup.dir</name>
    <description>Backup dir for HDFS</description>
    <value>/tmp/nfs</value>
  </property>
  -->

  <property>
    <name>mesos.hdfs.native-hadoop-binaries</name>
    <description>Mark true if you have hadoop pre-installed on your host machines (otherwise it will be distributed by the scheduler)</description>
    <value>false</value>
  </property>

  <property>
    <name>mesos.hdfs.framework.mnt.path</name>
    <description>Mount location (if mesos.hdfs.native-hadoop-binaries is marked false)</description>
    <value>/opt/mesosphere</value>
  </property>

  <property>
    <name>mesos.hdfs.state.zk</name>
    <description>Comma-separated hostname-port pairs of zookeeper node locations for HDFS framework state information</description>
    <value>zookeeper.service.consul:2181</value>
  </property>

  <property>
    <name>mesos.master.uri</name>
    <description>Zookeeper entry for mesos master location</description>
    <value>zk://zookeeper.service.consul:2181/mesos</value>
  </property>

  <property>
    <name>mesos.hdfs.zkfc.ha.zookeeper.quorum</name>
    <description>Comma-separated list of zookeeper hostname-port pairs for HDFS HA features</description>
    <value>zookeeper.service.consul:2181</value>
  </property>

  <property>
    <name>mesos.hdfs.framework.name</name>
    <description>Your Mesos framework name and cluster name when accessing files (hdfs://YOUR_NAME)</description>
    <value>hdfs</value>
  </property>

  <property>
    <name>mesos.hdfs.mesosdns</name>
    <description>Whether to use Mesos DNS for service discovery within HDFS</description>
    <value>false</value>
  </property>

  <property>
    <name>mesos.hdfs.mesosdns.domain</name>
    <description>Root domain name of Mesos DNS (usually 'mesos')</description>
    <value>mesos</value>
  </property>

  <property>
    <name>mesos.native.library</name>
    <description>Location of libmesos.so</description>
    <value>/usr/local/lib/libmesos.so</value>
  </property>

  <property>
    <name>mesos.hdfs.journalnode.count</name>
    <description>Number of journal nodes (must be odd)</description>
    <value>3</value>
  </property>

  <!-- Additional settings for fine-tuning -->

  <property>
    <name>mesos.hdfs.jvm.overhead</name>
    <description>Multiplier on resources reserved in order to account for JVM allocation</description>
    <value>1.35</value>
  </property>
  <property>
    <name>mesos.hdfs.hadoop.heap.size</name>
    <value>512</value>
  </property>
  <property>
    <name>mesos.hdfs.namenode.heap.size</name>
    <value>512</value>
  </property>
  <property>
    <name>mesos.hdfs.datanode.heap.size</name>
    <value>512</value>
  </property>
  <property>
    <name>mesos.hdfs.executor.heap.size</name>
    <value>256</value>
  </property>
  <property>
    <name>mesos.hdfs.executor.cpus</name>
    <value>0.1</value>
  </property>
  <property>
    <name>mesos.hdfs.namenode.cpus</name>
    <value>0.25</value>
  </property>
  <property>
    <name>mesos.hdfs.journalnode.cpus</name>
    <value>0.25</value>
  </property>
  <property>
    <name>mesos.hdfs.datanode.cpus</name>
    <value>0.25</value>
  </property>
  <property>
    <name>mesos.hdfs.user</name>
    <value>root</value>
  </property>
  <property>
    <name>mesos.hdfs.role</name>
    <value>*</value>
  </property>
   <property>
    <name>mesos.hdfs.ld-library-path</name>
    <value>/usr/local/lib</value>
  </property>
  <property>    
    <name>mesos.hdfs.datanode.exclusive</name>
    WARNING-It is not advisable to run the datanode on same slave because of performance issues
    <description>Whether to run the datanode on slave different from namenode and journal nodes</description>
    <value>true</value>
  </property>
</configuration>

Smarter uninstall

If you are running a package with a different app id, the uninstall has trouble finding it. We need to be able to support multiple instances of each package with the ability to uninstall specific instances

No way to install non-DCOS packages

By now Mantl-API leverages only one /repo/meta/index.json in the very last repo in it's repos list. I guess to have the possibility to create Mantl-specific packages we need to create our own index file in repo and slightly rewrite Mantl-API to merge indexes from all the repos.

Also it's a good idea to somehow generalize repo configuration for Mantl-API, make it configurable via some cli argument.

I'm working of both points if @ryane doesn't mind.

UI for installing / removing packages

The UI should:

  • show health (/health)
  • present a list of packages, listing installed state for each (/1/packages)
  • allow filtering unsupported packages (/1/packages)
  • install a package (POST /1/packages)
  • uninstall a package (DELETE /1/packages)
  • get all the details about a package (/1/packages/{name})

mantl-api panics when framework is nil

Hi @ryane

When packages.json does not contain a value for "framework":, mantl-api panics with the following message:

2016/05/06 19:48:34 http: panic serving 10.192.71.109:57460: interface conversion: interface is nil, not bool
goroutine 5249 [running]:
net/http.(*conn).serve.func1(0xc8200ca160, 0x7f6c035380c0, 0xc8201142e0)
    /usr/lib/go/src/net/http/server.go:1287 +0xb5
github.com/CiscoCloud/mantl-api/install.packageCatalog.packagesIndex(0xc8201d8240, 0xc820192048, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/catalog.go:82 +0x631
github.com/CiscoCloud/mantl-api/install.(*Install).getPackages(0xc8204db1a0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/package.go:324 +0xb2
github.com/CiscoCloud/mantl-api/install.(*Install).getPackageByName(0xc8204db1a0, 0xc820136110, 0x7, 0x0, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/package.go:328 +0x42
github.com/CiscoCloud/mantl-api/install.(*Install).Package(0xc8204db1a0, 0xc820136110, 0x7, 0x9a1f98, 0x0, 0x0)
    /go/src/github.com/CiscoCloud/mantl-api/install/install.go:62 +0x41
github.com/CiscoCloud/mantl-api/api.(*Api).describePackage(0xc8201db600, 0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0, 0xc820136180, 0x1, 0x1)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:99 +0xe4
github.com/CiscoCloud/mantl-api/api.(*Api).(github.com/CiscoCloud/mantl-api/api.describePackage)-fm(0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0, 0xc820136180, 0x1, 0x1)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:62 +0x5c
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0xc820011a80, 0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0)
    /go/src/github.com/julienschmidt/httprouter/router.go:344 +0x195
github.com/CiscoCloud/mantl-api/api.logHandler.func1(0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0)
    /go/src/github.com/CiscoCloud/mantl-api/api/api.go:43 +0x1a4
net/http.HandlerFunc.ServeHTTP(0xc8201db760, 0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0)
    /usr/lib/go/src/net/http/server.go:1422 +0x3a
net/http.serverHandler.ServeHTTP(0xc8204ee060, 0x7f6c035940d0, 0xc8200ca210, 0xc8204f42a0)
    /usr/lib/go/src/net/http/server.go:1862 +0x19e
net/http.(*conn).serve(0xc8200ca160)
    /usr/lib/go/src/net/http/server.go:1361 +0xbee
created by net/http.(*Server).Serve
    /usr/lib/go/src/net/http/server.go:1910 +0x3f6

on the customer end of the connection this appears as a 502 Bad Gateway error.

The problem mesosphere universe repos are:
./repo/packages/M/mysql/0/package.json
./repo/packages/M/mysql/1/package.json
./repo/packages/M/marathon-lb/0/package.json
./repo/packages/M/marathon-lb/1/package.json
./repo/packages/M/marathon-lb/4/package.json
./repo/packages/M/marathon-lb/2/package.json
./repo/packages/M/marathon-lb/3/package.json
./repo/packages/M/marathon/1/package.json
./repo/packages/M/marathon/2/package.json
./repo/packages/L/linkerd/0/package.json
./repo/packages/L/linkerd/1/package.json
./repo/packages/O/openvpn/0/package.json
./repo/packages/O/openvpn-admin/0/package.json
./repo/packages/N/nginx/0/package.json
./repo/packages/N/nginx/1/package.json
./repo/packages/N/namerd/0/package.json
./repo/packages/N/namerd/1/package.json
./repo/packages/W/weavescope/0/package.json
./repo/packages/W/weavescope-probe/0/package.json

I'm on rev 8783d7621439a3211d55ce5e22c128ee04a91d47 of mesosphere/universe and rev 1abaf95 of mantl-api.

I'd be happy to submit a PR for this, but before I do, would you prefer setting meta["framework"] to false if it is nil (with a warning) by wrapping https://github.com/CiscoCloud/mantl-api/blob/master/install/catalog.go#L82 inside an if block, OR should I wrap the whole of the package processing inside a test on err that warns on error but continues to the next package? I think the 2nd option might be more useful and would probably help close out #41 as well.

No way to install local packages.

Currently there is no possibility to specify local repo/package for Mantl API to install it.
I'm currently working on adding this functionality.

@ryane do you have any comments about this?

configurable CA cert for verifying Consul, Marathon, Mesos with TLS

There should be three new options:

--consul-ca-cert
--marathon-ca-cert
--mesos-ca-cert

All being the CA cert used to verify the Consul, Marathon, and Mesos servers' certificates. This will allow us to turn off consul-no-verify-ssl, marathon-no-verify-ssl, and mesos-no-verify-ssl in Mantl, since we now have valid self-signed certs 🎢

ability to specify load balancing mode

By default, mantl packages are exposed via the traefik load balancer on edge nodes. It should be possible to control this when installing packages (should it be off by default?). When mantl supports internal load balancing, it should be possible to configure load balancing to something like off | edge | internal.

ping @emdem

install supported package when version not requested

Installing a package without a specific version requested should install the latest supported version of the package.

Currently, it will attempt to install the latest version of a package even if it is not supported.

mesos framework is not always tore down successfully

When uninstalling hdfs, for example, we often see an error like

time="2015-09-29T15:46:05Z" level=debug msg="POST http://leader.mesos.service.consul:15050/master/teardown" method=POST status="400 Bad Request" statusCode=400 url="http://leader.mesos.service.consul:15050/master/teardown"

And the framework has to be removed manually

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.