You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2017/04/14 01:47:52 UTC

[1/4] mesos git commit: Windows: Fixed Base64Test.EncodeURLSafe.

Repository: mesos
Updated Branches:
  refs/heads/master 5660d7633 -> e370b0997


Windows: Fixed Base64Test.EncodeURLSafe.

C++ encodes string literals in the compiling platform's encoding
of choice, which means UTF8 for Posix, and ANSI for Windows.

This has implications for this particular test, as the string literal
"~~~\u00ff\u00ff\u00ff\u00ff" is translated into different bytes:
  Posix:   { 126, 126, 126, 195, 191, 195, 191, 195, 191, 195, 191 }
  Windows: { 126, 126, 126,      255,      255,      255,      255 }

Prepending `u8` to the string literal tells the compiler to encode
the string as UTF8.  This does not expose any underlying bug(s)
on Windows because the test is only failing due to an incorrect input.

Review: https://reviews.apache.org/r/58430/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/703d0011
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/703d0011
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/703d0011

Branch: refs/heads/master
Commit: 703d0011d9049c6003f6d57026f5e764d1cb4435
Parents: 5660d76
Author: John Kordich <jo...@microsoft.com>
Authored: Thu Apr 13 18:07:25 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Thu Apr 13 18:07:25 2017 -0700

----------------------------------------------------------------------
 3rdparty/stout/tests/base64_tests.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/703d0011/3rdparty/stout/tests/base64_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/base64_tests.cpp b/3rdparty/stout/tests/base64_tests.cpp
index 0473221..a6837c8 100644
--- a/3rdparty/stout/tests/base64_tests.cpp
+++ b/3rdparty/stout/tests/base64_tests.cpp
@@ -56,12 +56,12 @@ TEST(Base64Test, EncodeURLSafe)
       base64::encode_url_safe("user:password~~~", true));
 
   EXPECT_EQ(
-      "fn5-w7_Dv8O_w78",
-      base64::encode_url_safe("~~~\u00ff\u00ff\u00ff\u00ff", false));
+      u8"fn5-w7_Dv8O_w78",
+      base64::encode_url_safe(u8"~~~\u00ff\u00ff\u00ff\u00ff", false));
 
   EXPECT_EQ(
-      "fn5-w7_Dv8O_w78=",
-      base64::encode_url_safe("~~~\u00ff\u00ff\u00ff\u00ff", true));
+      u8"fn5-w7_Dv8O_w78=",
+      base64::encode_url_safe(u8"~~~\u00ff\u00ff\u00ff\u00ff", true));
 }
 
 
@@ -76,10 +76,10 @@ TEST(Base64Test, DecodeURLSafe)
       base64::decode_url_safe("dXNlcjpwYXNzd29yZH5-fg=="));
 
   EXPECT_SOME_EQ(
-      "~~~\u00ff\u00ff\u00ff\u00ff",
-      base64::decode_url_safe("fn5-w7_Dv8O_w78"));
+      u8"~~~\u00ff\u00ff\u00ff\u00ff",
+      base64::decode_url_safe(u8"fn5-w7_Dv8O_w78"));
 
   EXPECT_SOME_EQ(
-      "~~~\u00ff\u00ff\u00ff\u00ff",
-      base64::decode_url_safe("fn5-w7_Dv8O_w78="));
+      u8"~~~\u00ff\u00ff\u00ff\u00ff",
+      base64::decode_url_safe(u8"fn5-w7_Dv8O_w78="));
 }


[2/4] mesos git commit: CLI: Added a Table abstraction.

Posted by jo...@apache.org.
CLI: Added a Table abstraction.

This utility class helps print information in left-aligned columns.
This will be used by future plugins.

NOTE: The original review was posted by Kevin Klues on behalf of
Haris Choudhary ( https://reviews.apache.org/r/52948/ ).

Review: https://reviews.apache.org/r/58381/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/12e4812e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/12e4812e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/12e4812e

Branch: refs/heads/master
Commit: 12e4812e360d553539a810512d08bef6434d48af
Parents: 703d001
Author: Haris Choudhary <ha...@gmail.com>
Authored: Thu Apr 13 18:22:01 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Thu Apr 13 18:22:40 2017 -0700

----------------------------------------------------------------------
 src/cli_new/lib/cli/util.py | 93 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/12e4812e/src/cli_new/lib/cli/util.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/util.py b/src/cli_new/lib/cli/util.py
index ace07fb..27c4f17 100644
--- a/src/cli_new/lib/cli/util.py
+++ b/src/cli_new/lib/cli/util.py
@@ -21,6 +21,7 @@ A collection of helper functions used by the CLI and its Plugins.
 import imp
 import importlib
 import os
+import re
 import textwrap
 
 from cli.exceptions import CLIException
@@ -149,3 +150,95 @@ def format_subcommands_help(cmd):
             flag_string += "  %s%s%s\n" % (flag, " " * num_spaces, flags[flag])
 
     return (arguments, short_help, long_help, flag_string)
+
+
+class Table(object):
+    """
+    Defines a custom table structure for printing to the terminal.
+    """
+    def __init__(self, columns):
+        """
+        Initialize a table with a list of column names
+        to act as headers for each column in the table.
+        """
+        if not isinstance(columns, list):
+            raise CLIException("Column headers must be supplied as a list")
+
+        for column in columns:
+            if re.search(r"(\s)\1{2,}", column):
+                raise CLIException("Column headers cannot have more"
+                                   " than one space between words")
+
+        self.table = [columns]
+        self.padding = [len(column) for column in columns]
+
+    def __getitem__(self, index):
+        return list(self.table[index])
+
+    def dimensions(self):
+        """
+        Returns the dimensions of the table as (<num-rows>, <num-columns>).
+        """
+        return (len(self.table), len(self.table[0]))
+
+    def add_row(self, row):
+        """
+        Add a row to the table. Input must be a list where each entry
+        corresponds to its respective column in order.
+        """
+        if len(row) != len(self.table[0]):
+            raise CLIException("Number of entries and columns do not match!")
+
+        # Adjust padding for each column.
+        for index, elem in enumerate(row):
+            if len(elem) > self.padding[index]:
+                self.padding[index] = len(elem)
+
+        self.table.append(row)
+
+    def __str__(self):
+        """
+        Convert a table to string for printing.
+        """
+        table_string = ""
+        for r_index, row in enumerate(self.table):
+            for index, entry in enumerate(row):
+                table_string += "%s%s" % \
+                        (entry, " " * (self.padding[index] - len(entry) + 2))
+
+            if r_index != len(self.table) - 1:
+                table_string += "\n"
+
+        return table_string
+
+    @staticmethod
+    def parse(string):
+        """
+        Parse a string previously printed as a `Table` back into a `Table`.
+        """
+        lines = string.split("\n")
+
+        # Find the location and contents of column headers in the string.
+        # Assume only single spaces between words in column headers.
+        matches = re.finditer(r"([\w\d]+\s?[\w\d]+)+", lines[0])
+        columns = [(m.start(), m.group()) for m in matches]
+
+        # Build a table from the column header contents.
+        table = Table([c[1] for c in columns])
+
+        # Fill in the subsequent rows.
+        for line in lines[1:]:
+            row = []
+            start_indices = [c[0] for c in columns]
+
+            for i, start_index in enumerate(start_indices):
+                if i + 1 < len(start_indices):
+                    column = line[start_index:start_indices[i + 1]]
+                else:
+                    column = line[start_index:]
+
+                row.append(str(column.strip()))
+
+            table.add_row(row)
+
+        return table


[4/4] mesos git commit: CLI: Added 'config' plugin.

Posted by jo...@apache.org.
CLI: Added 'config' plugin.

The 'config' plugin will be used to read, validate, and potentially
write the Mesos CLI configuration file.

This commit adds the skeleton for the plugin as well as a simple
command to show the available plugins.

Review: https://reviews.apache.org/r/57952/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e370b099
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e370b099
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e370b099

Branch: refs/heads/master
Commit: e370b0997d8c20ffa205c8a9f58111051666b6d3
Parents: 8f13ad8
Author: Armand Grillet <ag...@mesosphere.io>
Authored: Thu Apr 13 18:40:00 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Thu Apr 13 18:44:46 2017 -0700

----------------------------------------------------------------------
 src/cli_new/bin/settings.py                    |  4 +-
 src/cli_new/lib/cli/plugins/config/__init__.py | 22 +++++++
 src/cli_new/lib/cli/plugins/config/main.py     | 68 +++++++++++++++++++++
 3 files changed, 93 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e370b099/src/cli_new/bin/settings.py
----------------------------------------------------------------------
diff --git a/src/cli_new/bin/settings.py b/src/cli_new/bin/settings.py
index 8dbb160..0ef07cc 100644
--- a/src/cli_new/bin/settings.py
+++ b/src/cli_new/bin/settings.py
@@ -40,7 +40,9 @@ except Exception:
 PROJECT_DIR = os.path.join(os.path.dirname(__file__), os.pardir)
 
 # The builtin plugins.
-PLUGINS = []
+PLUGINS = [
+    os.path.join(PROJECT_DIR, "lib/mesos/plugins", "config")
+]
 
 MESOS_CLI_DEFAULT_CONFIG_PATH = os.path.join(
     os.path.expanduser("~"), ".mesos/config.toml")

http://git-wip-us.apache.org/repos/asf/mesos/blob/e370b099/src/cli_new/lib/cli/plugins/config/__init__.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/plugins/config/__init__.py b/src/cli_new/lib/cli/plugins/config/__init__.py
new file mode 100644
index 0000000..cf5673d
--- /dev/null
+++ b/src/cli_new/lib/cli/plugins/config/__init__.py
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+"""
+Config module.
+"""
+
+# pylint: disable=wildcard-import
+from .main import *

http://git-wip-us.apache.org/repos/asf/mesos/blob/e370b099/src/cli_new/lib/cli/plugins/config/main.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/plugins/config/main.py b/src/cli_new/lib/cli/plugins/config/main.py
new file mode 100644
index 0000000..d95a36f
--- /dev/null
+++ b/src/cli_new/lib/cli/plugins/config/main.py
@@ -0,0 +1,68 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+"""
+The config plugin.
+"""
+
+import sys
+
+import settings
+import cli
+
+from cli.plugins import PluginBase
+from cli.util import Table
+
+
+PLUGIN_NAME = "config"
+PLUGIN_CLASS = "Config"
+
+VERSION = "Mesos CLI Config Plugin"
+
+SHORT_HELP = "Interacts with the Mesos CLI configuration file"
+
+
+class Config(PluginBase):
+    """
+    The config plugin.
+    """
+
+    COMMANDS = {
+        "plugins": {
+            "arguments": [],
+            "flags": {},
+            "short_help": "Print the plugins that can be used.",
+            "long_help": "Print the plugins that can be used."
+        }
+    }
+
+    def plugins(self, argv):
+        """
+        Parse and load the builtin plugins and the ones in the configuration
+        file. If this method is called using 'mesos config plugins', it
+        displays the plugins that can be used.
+        """
+        # pylint: disable=unused-argument
+        plugins_table = Table(["NAME", "DESCRIPTION"])
+
+        # Load the plugins
+        loaded_plugins = cli.util.import_modules(settings.PLUGINS, "plugins")
+        for plugin in loaded_plugins:
+            plugins_table.add_row([
+                cli.util.get_module(loaded_plugins, plugin).PLUGIN_NAME,
+                cli.util.get_module(loaded_plugins, plugin).SHORT_HELP
+            ])
+        sys.stdout.write("{}\n".format(plugins_table))


[3/4] mesos git commit: CLI: Moved settings into a user-defined TOML file.

Posted by jo...@apache.org.
CLI: Moved settings into a user-defined TOML file.

These settings were previously defined and set in settings.py.

We now use a TOML file containing the configuration,
this format has been chosen because:
  * It supports comments.
  * It is well-specified and readable.
  * It allows logical grouping.
  * It supports common data types.

The config file environment variable, previously
`MESOS_CLI_CONFIG_PATH`, is now `MESOS_CLI_CONFIG`.
This change follows the design doc about the new CLI.

Also, the environment variable `MESOS_CLI_PLUGINS` is not used
anymore as plugins can be added using the TOML file instead.

Review: https://reviews.apache.org/r/57951/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8f13ad86
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8f13ad86
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8f13ad86

Branch: refs/heads/master
Commit: 8f13ad8688f13fcbdfde08f36428bf4db266d94e
Parents: 12e4812
Author: Armand Grillet <ag...@mesosphere.io>
Authored: Thu Apr 13 18:34:57 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Thu Apr 13 18:34:57 2017 -0700

----------------------------------------------------------------------
 src/cli_new/README.md            | 20 +++++++++++++
 src/cli_new/bin/settings.py      | 55 +++++++++++++++++++----------------
 src/cli_new/pip-requirements.txt |  1 +
 3 files changed, 51 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8f13ad86/src/cli_new/README.md
----------------------------------------------------------------------
diff --git a/src/cli_new/README.md b/src/cli_new/README.md
index aa11813..c5475c7 100644
--- a/src/cli_new/README.md
+++ b/src/cli_new/README.md
@@ -61,3 +61,23 @@ Running the Mesos CLI unit tests
 
 OK
 ```
+
+
+## Setting up your configuration
+
+In order to use this tool, you will need to create a
+configuration file in your home directory under
+`~/.mesos/config.toml`. A template for this config can be
+seen below:
+
+```
+# The `plugins` is an array listing the absolute paths of the
+# plugins you want to add to the CLI.
+plugins = [
+  "</absolute/path/to/plugin-1/directory>",
+  "</absolute/path/to/plugin-2/directory>"
+]
+```
+
+You can override the location of this configuration file using
+the environment variable `MESOS_CLI_CONFIG`.

http://git-wip-us.apache.org/repos/asf/mesos/blob/8f13ad86/src/cli_new/bin/settings.py
----------------------------------------------------------------------
diff --git a/src/cli_new/bin/settings.py b/src/cli_new/bin/settings.py
index 2f6162e..8dbb160 100644
--- a/src/cli_new/bin/settings.py
+++ b/src/cli_new/bin/settings.py
@@ -20,9 +20,8 @@ of updating the default configuration from reading environment variables or
 parsing a configuration file.
 """
 
-import json
 import os
-import sys
+import toml
 
 from cli.exceptions import CLIException
 
@@ -37,35 +36,41 @@ try:
 except Exception:
     VERSION = "Development"
 
+# The top-level directory of this project.
+PROJECT_DIR = os.path.join(os.path.dirname(__file__), os.pardir)
 
 # The builtin plugins.
 PLUGINS = []
 
+MESOS_CLI_DEFAULT_CONFIG_PATH = os.path.join(
+    os.path.expanduser("~"), ".mesos/config.toml")
 
-# Allow extra plugins to be pulled in from a configuration file.
-if os.environ.get("MESOS_CLI_CONFIG_FILE"):
-    try:
-        CONFIG_FILE = open(os.environ["MESOS_CLI_CONFIG_FILE"])
-    except Exception as exception:
-        sys.exit("Unable to open configuration file '{config}': {error}"
-                 .format(config=os.environ.get("MESOS_CLI_CONFIG_FILE"),
-                         error=str(exception)))
+# Load the configuration file path for the CLI.
+if os.environ.get("MESOS_CLI_CONFIG"):
+    MESOS_CLI_CONFIG_PATH = os.environ["MESOS_CLI_CONFIG"]
+else:
+    MESOS_CLI_CONFIG_PATH = MESOS_CLI_DEFAULT_CONFIG_PATH
 
-    try:
-        CONFIG_DATA = json.load(CONFIG_FILE)
-    except Exception as exception:
-        raise CLIException("Error loading config file as JSON: {error}"
+# Load the configuration file as a TOML file.
+try:
+    CONFIG_DATA = toml.load(MESOS_CLI_CONFIG_PATH)
+except Exception as exception:
+    if MESOS_CLI_CONFIG_PATH is not MESOS_CLI_DEFAULT_CONFIG_PATH:
+        raise CLIException("Error loading config file as TOML: {error}"
                            .format(error=exception))
+    else:
+        CONFIG_DATA = {}
 
-    if "plugins" in CONFIG_DATA:
-        if not isinstance(CONFIG_DATA["plugins"], list):
-            raise CLIException("'plugins' field must be a list")
-
-        PLUGINS.extend(CONFIG_DATA["plugins"])
-
+# Allow extra plugins to be pulled in from the configuration file.
+if "plugins" in CONFIG_DATA:
+    if not isinstance(CONFIG_DATA["plugins"], list):
+        raise CLIException("Unable to parse config file '{path}': 'plugins' "
+                           "field must be a list"
+                           .format(path=MESOS_CLI_CONFIG_PATH))
 
-# Allow extra plugins to be pulled in from the environment.
-# The `MESOS_CLI_PLUGINS` environment variable is a ":" separated
-# list of paths to each plugin. All paths must be absolute.
-if os.environ.get("MESOS_CLI_PLUGINS"):
-    PLUGINS += filter(None, os.environ.get("MESOS_CLI_PLUGINS").split(":"))
+    for plugin in CONFIG_DATA["plugins"]:
+        if os.path.exists(plugin):
+            PLUGINS.append(plugin)
+        else:
+            raise CLIException("Plugin path not found: {path}"
+                               .format(path=plugin))

http://git-wip-us.apache.org/repos/asf/mesos/blob/8f13ad86/src/cli_new/pip-requirements.txt
----------------------------------------------------------------------
diff --git a/src/cli_new/pip-requirements.txt b/src/cli_new/pip-requirements.txt
index e73bbfd..28613e5 100644
--- a/src/cli_new/pip-requirements.txt
+++ b/src/cli_new/pip-requirements.txt
@@ -10,4 +10,5 @@ PyInstaller==3.1.1
 pylint==1.6.4
 six==1.10.0
 termcolor==1.1.0
+toml==0.9.2
 wrapt==1.10.8