SLIDER-787 App Upgrade/Reconfig support in Slider (introduce version in app 
packages)


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

Branch: refs/heads/develop
Commit: e3021a045f72829755ab6d401fbb990c2c47d824
Parents: 226e27e
Author: Gour Saha <[email protected]>
Authored: Wed Apr 1 13:38:08 2015 -0700
Committer: Gour Saha <[email protected]>
Committed: Wed Apr 1 14:06:20 2015 -0700

----------------------------------------------------------------------
 app-packages/accumulo/appConfig-default.json    |   1 +
 .../accumulo/appConfig-secured-default.json     |   1 +
 .../accumulo/appConfig-ssl-default.json         |   1 +
 app-packages/accumulo/package/scripts/params.py |   1 +
 .../app-pkg-template/appConfig-default.json     |   1 +
 .../app-pkg-template/package/scripts/params.py  |   1 +
 .../command-logger/slider-pkg/appConfig.json    |   1 +
 .../slider-pkg/package/scripts/params.py        |   1 +
 app-packages/hbase-win/appConfig-default.json   |   1 +
 .../hbase-win/package/scripts/params.py         |   1 +
 app-packages/hbase/appConfig-default.json       |   1 +
 .../hbase/appConfig-phoenix-default.json        |   1 +
 .../hbase/appConfig-secured-default.json        |   1 +
 app-packages/hbase/package/scripts/params.py    |   1 +
 .../test/resources/appConfig_monitor_ssl.json   |   1 +
 .../memcached-win/appConfig-default.json        |   1 +
 .../memcached-win/package/scripts/params.py     |   1 +
 app-packages/memcached/appConfig-default.json   |   1 +
 .../memcached/package/scripts/params.py         |   1 +
 app-packages/storm-win/appConfig-default.json   |   1 +
 .../storm-win/package/scripts/params.py         |   1 +
 app-packages/storm/appConfig-default.json       |   1 +
 .../storm/appConfig-secured-default.json        |   1 +
 app-packages/storm/package/scripts/params.py    |   1 +
 .../org/apache/slider/api/proto/Messages.java   | 443 ++++++++++++++++---
 .../slider/api/proto/RestTypeMarshalling.java   |   4 +
 .../slider/api/types/ContainerInformation.java  |   1 +
 .../org/apache/slider/client/SliderClient.java  |  51 ++-
 .../org/apache/slider/common/SliderKeys.java    |   5 +
 .../slider/common/params/ActionPackageArgs.java |   3 +
 .../apache/slider/common/params/Arguments.java  |   1 +
 .../slider/common/tools/CoreFileSystem.java     |  10 +-
 .../apache/slider/common/tools/SliderUtils.java |  24 +-
 .../apache/slider/core/conf/AggregateConf.java  |  13 +
 .../providers/agent/AgentClientProvider.java    |  12 +-
 .../providers/agent/AgentProviderService.java   |   8 +-
 .../server/appmaster/RoleLaunchService.java     |   3 +
 .../server/appmaster/SliderAppMaster.java       |   2 +-
 .../server/appmaster/state/RoleInstance.java    |   7 +
 .../src/main/proto/SliderClusterMessages.proto  |   4 +-
 .../slider/agent/actions/TestActionList.groovy  | 104 +++++
 .../client/TestPackageCommandOptions.groovy     | 117 ++++-
 42 files changed, 729 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/accumulo/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/accumulo/appConfig-default.json 
b/app-packages/accumulo/appConfig-default.json
index 85c6985..e6e8149 100644
--- a/app-packages/accumulo/appConfig-default.json
+++ b/app-packages/accumulo/appConfig-default.json
@@ -6,6 +6,7 @@
     "application.def": ".slider/package/ACCUMULO/${app.package.name}.zip",
     "java_home": "${app.java.home}",
 
+    "site.global.app_version": "${accumulo.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/accumulo-${accumulo.version}",
     "site.global.app_user": "${app.user}",
     "site.global.user_group": "${app.user.group}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/accumulo/appConfig-secured-default.json
----------------------------------------------------------------------
diff --git a/app-packages/accumulo/appConfig-secured-default.json 
b/app-packages/accumulo/appConfig-secured-default.json
index 347259f..40c38c0 100644
--- a/app-packages/accumulo/appConfig-secured-default.json
+++ b/app-packages/accumulo/appConfig-secured-default.json
@@ -6,6 +6,7 @@
     "application.def": ".slider/package/ACCUMULO/${app.package.name}.zip",
     "java_home": "${app.java.home}",
 
+    "site.global.app_version": "${accumulo.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/accumulo-${accumulo.version}",
     "site.global.app_user": "${USER}",
     "site.global.user_group": "${USER}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/accumulo/appConfig-ssl-default.json
----------------------------------------------------------------------
diff --git a/app-packages/accumulo/appConfig-ssl-default.json 
b/app-packages/accumulo/appConfig-ssl-default.json
index 9781e5f..5f213c2 100644
--- a/app-packages/accumulo/appConfig-ssl-default.json
+++ b/app-packages/accumulo/appConfig-ssl-default.json
@@ -9,6 +9,7 @@
     "slider.component.keystore.credential.alias.property": 
"rpc.javax.net.ssl.keyStorePassword",
     "slider.component.truststore.credential.alias.property": 
"rpc.javax.net.ssl.trustStorePassword",
 
+    "site.global.app_version": "${accumulo.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/accumulo-${accumulo.version}",
     "site.global.app_user": "${app.user}",
     "site.global.user_group": "${app.user.group}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/accumulo/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/accumulo/package/scripts/params.py 
b/app-packages/accumulo/package/scripts/params.py
index 29a7c7d..fc3ba45 100644
--- a/app-packages/accumulo/package/scripts/params.py
+++ b/app-packages/accumulo/package/scripts/params.py
@@ -45,6 +45,7 @@ env_sh_template = 
config['configurations']['accumulo-env']['content']
 
 # accumulo local directory structure
 accumulo_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 app_name = config['clusterName']
 conf_dir = format("{accumulo_root}/conf")
 log_dir = config['configurations']['global']['app_log_dir']

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/app-pkg-template/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/app-pkg-template/appConfig-default.json 
b/app-packages/app-pkg-template/appConfig-default.json
index cc65503..8328421 100644
--- a/app-packages/app-pkg-template/appConfig-default.json
+++ b/app-packages/app-pkg-template/appConfig-default.json
@@ -6,6 +6,7 @@
     "application.def": "myapp-1.0.0.zip",
     "java_home": "/usr/jdk64/jdk1.7.0_67",
 
+    "site.global.app_version": "1.0.0",
     "site.global.app_root": "${AGENT_WORK_ROOT}/app/install/myapp-1.0.0",
 
     "site.global.listen_port": "${MYAPP_COMPONENT.ALLOCATED_PORT}"

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/app-pkg-template/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/app-pkg-template/package/scripts/params.py 
b/app-packages/app-pkg-template/package/scripts/params.py
index e81bda0..a41b8d8 100644
--- a/app-packages/app-pkg-template/package/scripts/params.py
+++ b/app-packages/app-pkg-template/package/scripts/params.py
@@ -24,6 +24,7 @@ from resource_management import *
 config = Script.get_config()
 
 app_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 java64_home = config['hostLevelParams']['java_home']
 app_user = config['configurations']['global']['app_user']
 port = config['configurations']['global']['listen_port']

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/command-logger/slider-pkg/appConfig.json
----------------------------------------------------------------------
diff --git a/app-packages/command-logger/slider-pkg/appConfig.json 
b/app-packages/command-logger/slider-pkg/appConfig.json
index 884b2e2..a9e14d3 100644
--- a/app-packages/command-logger/slider-pkg/appConfig.json
+++ b/app-packages/command-logger/slider-pkg/appConfig.json
@@ -6,6 +6,7 @@
     "application.def": 
".slider/package/CMD_LOGGER/command-logger-slider-package.zip",
     "java_home": "/usr/jdk64/jdk1.7.0_67",
     "site.global.application_id": "CommandLogger",
+    "site.global.app_version": "1.0.0",
     "site.global.app_root": "${AGENT_WORK_ROOT}/app/install/command-logger",
     "site.cl-site.logfile.location": 
"${AGENT_WORK_ROOT}/app/install/command-logger-app/operations.log",
     "site.cl-site.datetime.format": "%A, %d. %B %Y %I:%M%p",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/command-logger/slider-pkg/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/command-logger/slider-pkg/package/scripts/params.py 
b/app-packages/command-logger/slider-pkg/package/scripts/params.py
index b135539..2ec9c64 100644
--- a/app-packages/command-logger/slider-pkg/package/scripts/params.py
+++ b/app-packages/command-logger/slider-pkg/package/scripts/params.py
@@ -23,6 +23,7 @@ from resource_management import *
 # server configurations
 config = Script.get_config()
 
+app_version = config['configurations']['global']['app_version']
 container_id = config['hostLevelParams']['container_id']
 application_id = config['configurations']['global']['application_id']
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase-win/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/hbase-win/appConfig-default.json 
b/app-packages/hbase-win/appConfig-default.json
index 719a743..d3b19d0 100644
--- a/app-packages/hbase-win/appConfig-default.json
+++ b/app-packages/hbase-win/appConfig-default.json
@@ -8,6 +8,7 @@
         "java_home": "C:\\java",
 
         "site.global.app_user": "hadoop",
+        "site.global.app_version": "${hbase.version}",
         "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/hbase-${hbase.version}",
         "site.global.hbase_instance_name": "instancename",
         "site.global.user_group": "hadoop",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase-win/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/hbase-win/package/scripts/params.py 
b/app-packages/hbase-win/package/scripts/params.py
index 5a54e25..8153540 100644
--- a/app-packages/hbase-win/package/scripts/params.py
+++ b/app-packages/hbase-win/package/scripts/params.py
@@ -27,6 +27,7 @@ config = Script.get_config()
 
 java64_home = config['hostLevelParams']['java_home']
 hbase_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 hbase_instance_name = config['configurations']['global']['hbase_instance_name']
 hbase_user = status_params.hbase_user
 user_group = config['configurations']['global']['user_group']

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/hbase/appConfig-default.json 
b/app-packages/hbase/appConfig-default.json
index 4a91884..9285f97 100644
--- a/app-packages/hbase/appConfig-default.json
+++ b/app-packages/hbase/appConfig-default.json
@@ -9,6 +9,7 @@
         "system_configs": "core-site",
 
         "site.global.app_user": "yarn",
+        "site.global.app_version": "${hbase.version}",
         "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/hbase-${hbase.version}",
 
         "site.global.metric_collector_host": "${NN_HOST}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase/appConfig-phoenix-default.json
----------------------------------------------------------------------
diff --git a/app-packages/hbase/appConfig-phoenix-default.json 
b/app-packages/hbase/appConfig-phoenix-default.json
index 68df0cc..00c77f0 100644
--- a/app-packages/hbase/appConfig-phoenix-default.json
+++ b/app-packages/hbase/appConfig-phoenix-default.json
@@ -9,6 +9,7 @@
         "system_configs": "core-site",
 
         "site.global.app_user": "yarn",
+        "site.global.app_version": "${hbase.version}",
         "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/hbase-${pkg.version}",
 
         "site.global.metric_collector_host": "${NN_HOST}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase/appConfig-secured-default.json
----------------------------------------------------------------------
diff --git a/app-packages/hbase/appConfig-secured-default.json 
b/app-packages/hbase/appConfig-secured-default.json
index 553117e..46ee06e 100644
--- a/app-packages/hbase/appConfig-secured-default.json
+++ b/app-packages/hbase/appConfig-secured-default.json
@@ -9,6 +9,7 @@
         "system_configs": "core-site,hdfs-site",
 
         "site.global.app_user": "${USER_NAME}",
+        "site.global.app_version": "${hbase.version}",
         "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/hbase-${pkg.version}",
 
         "site.global.metric_collector_host": "${NN_HOST}",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/hbase/package/scripts/params.py 
b/app-packages/hbase/package/scripts/params.py
index 578ca64..45127d5 100644
--- a/app-packages/hbase/package/scripts/params.py
+++ b/app-packages/hbase/package/scripts/params.py
@@ -26,6 +26,7 @@ import status_params
 config = Script.get_config()
 
 hbase_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 app_name = config['clusterName']
 conf_dir = format("{hbase_root}/conf")
 daemon_script = format("{hbase_root}/bin/hbase-daemon.sh")

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/hbase/src/test/resources/appConfig_monitor_ssl.json
----------------------------------------------------------------------
diff --git a/app-packages/hbase/src/test/resources/appConfig_monitor_ssl.json 
b/app-packages/hbase/src/test/resources/appConfig_monitor_ssl.json
index 73b33ed..64dd457 100644
--- a/app-packages/hbase/src/test/resources/appConfig_monitor_ssl.json
+++ b/app-packages/hbase/src/test/resources/appConfig_monitor_ssl.json
@@ -12,6 +12,7 @@
     "site.global.app_user": "yarn",
     "site.global.app_log_dir": "app/log",
     "site.global.app_pid_dir": "${AGENT_WORK_ROOT}/app/run",
+    "site.global.app_version": "${hbase.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/hbase-${hbase.version}",
     "site.global.app_install_dir": "${AGENT_WORK_ROOT}/app/install",
     "site.global.hbase_master_heapsize": "1024m",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/memcached-win/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/memcached-win/appConfig-default.json 
b/app-packages/memcached-win/appConfig-default.json
index 8a5ffd0..54dd564 100644
--- a/app-packages/memcached-win/appConfig-default.json
+++ b/app-packages/memcached-win/appConfig-default.json
@@ -6,6 +6,7 @@
     "application.def": ".slider/package/MEMCACHED/jmemcached-1.0.0.zip",
     "java_home": "C:\\java",
 
+    "site.global.app_version": "1.0.0",
     "site.global.additional_cp": 
"C:\\hdp\\hadoop-2.4.0.2.1.3.0-1990\\share\\hadoop\\common\\lib\\*",
     "site.global.xmx_val": "256m",
     "site.global.xms_val": "128m",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/memcached-win/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/memcached-win/package/scripts/params.py 
b/app-packages/memcached-win/package/scripts/params.py
index 056a3b9..935ba11 100644
--- a/app-packages/memcached-win/package/scripts/params.py
+++ b/app-packages/memcached-win/package/scripts/params.py
@@ -24,6 +24,7 @@ from resource_management import *
 config = Script.get_config()
 
 app_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 java64_home = config['hostLevelParams']['java_home']
 pid_file = config['configurations']['global']['pid_file']
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/memcached/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/memcached/appConfig-default.json 
b/app-packages/memcached/appConfig-default.json
index 16dd931..848e718 100644
--- a/app-packages/memcached/appConfig-default.json
+++ b/app-packages/memcached/appConfig-default.json
@@ -6,6 +6,7 @@
     "application.def": ".slider/package/MEMCACHED/jmemcached-1.0.0.zip",
     "java_home": "/usr/jdk64/jdk1.7.0_67",
 
+    "site.global.app_version": "1.0.0",
     "site.global.additional_cp": "/usr/lib/hadoop/lib/*",
     "site.global.xmx_val": "256m",
     "site.global.xms_val": "128m",

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/memcached/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/memcached/package/scripts/params.py 
b/app-packages/memcached/package/scripts/params.py
index 970638a..0ef4533 100644
--- a/app-packages/memcached/package/scripts/params.py
+++ b/app-packages/memcached/package/scripts/params.py
@@ -24,6 +24,7 @@ from resource_management import *
 config = Script.get_config()
 
 app_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 java64_home = config['hostLevelParams']['java_home']
 pid_file = config['configurations']['global']['pid_file']
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/storm-win/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/storm-win/appConfig-default.json 
b/app-packages/storm-win/appConfig-default.json
index a77f00d..b48efee 100644
--- a/app-packages/storm-win/appConfig-default.json
+++ b/app-packages/storm-win/appConfig-default.json
@@ -8,6 +8,7 @@
     "create.default.zookeeper.node": "true",
 
     "site.global.app_user": "hadoop",
+    "site.global.app_version": "${storm.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/storm-${pkg.version}",
     "site.global.user_group": "hadoop",
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/storm-win/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/storm-win/package/scripts/params.py 
b/app-packages/storm-win/package/scripts/params.py
index 21e5c65..755ce12 100644
--- a/app-packages/storm-win/package/scripts/params.py
+++ b/app-packages/storm-win/package/scripts/params.py
@@ -25,6 +25,7 @@ import status_params
 config = Script.get_config()
 
 app_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 conf_dir = format("{app_root}/conf")
 storm_user = config['configurations']['global']['app_user']
 log_dir = config['configurations']['global']['app_log_dir']

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/storm/appConfig-default.json
----------------------------------------------------------------------
diff --git a/app-packages/storm/appConfig-default.json 
b/app-packages/storm/appConfig-default.json
index e04bb9c..0deff7c 100644
--- a/app-packages/storm/appConfig-default.json
+++ b/app-packages/storm/appConfig-default.json
@@ -8,6 +8,7 @@
     "create.default.zookeeper.node": "true",
 
     "site.global.app_user": "${USER_NAME}",
+    "site.global.app_version": "${storm.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/apache-storm-${storm.version}",
     "site.global.user_group": "hadoop",
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/storm/appConfig-secured-default.json
----------------------------------------------------------------------
diff --git a/app-packages/storm/appConfig-secured-default.json 
b/app-packages/storm/appConfig-secured-default.json
index 2d51a9b..2ed65fc 100644
--- a/app-packages/storm/appConfig-secured-default.json
+++ b/app-packages/storm/appConfig-secured-default.json
@@ -8,6 +8,7 @@
     "create.default.zookeeper.node": "true",
 
     "site.global.app_user": "${USER_NAME}",
+    "site.global.app_version": "${storm.version}",
     "site.global.app_root": 
"${AGENT_WORK_ROOT}/app/install/apache-storm-${pkg.version}",
     "site.global.user_group": "hadoop",
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/app-packages/storm/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/app-packages/storm/package/scripts/params.py 
b/app-packages/storm/package/scripts/params.py
index 379b229..b701698 100644
--- a/app-packages/storm/package/scripts/params.py
+++ b/app-packages/storm/package/scripts/params.py
@@ -25,6 +25,7 @@ import status_params
 config = Script.get_config()
 
 app_root = config['configurations']['global']['app_root']
+app_version = config['configurations']['global']['app_version']
 app_name = config['clusterName']
 conf_dir = format("{app_root}/conf")
 storm_user = config['configurations']['global']['app_user']

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java 
b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
index 44771e5..845f498 100644
--- a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
+++ b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java
@@ -200,6 +200,21 @@ public final class Messages {
      */
     com.google.protobuf.ByteString
         getHostURLBytes();
+
+    // required string appVersion = 16;
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    boolean hasAppVersion();
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    java.lang.String getAppVersion();
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    com.google.protobuf.ByteString
+        getAppVersionBytes();
   }
   /**
    * Protobuf type {@code org.apache.slider.api.RoleInstanceState}
@@ -328,6 +343,11 @@ public final class Messages {
               hostURL_ = input.readBytes();
               break;
             }
+            case 130: {
+              bitField0_ |= 0x00001000;
+              appVersion_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -788,6 +808,49 @@ public final class Messages {
       }
     }
 
+    // required string appVersion = 16;
+    public static final int APPVERSION_FIELD_NUMBER = 16;
+    private java.lang.Object appVersion_;
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    public boolean hasAppVersion() {
+      return ((bitField0_ & 0x00001000) == 0x00001000);
+    }
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    public java.lang.String getAppVersion() {
+      java.lang.Object ref = appVersion_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          appVersion_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string appVersion = 16;</code>
+     */
+    public com.google.protobuf.ByteString
+        getAppVersionBytes() {
+      java.lang.Object ref = appVersion_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        appVersion_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
     private void initFields() {
       name_ = "";
       role_ = "";
@@ -803,6 +866,7 @@ public final class Messages {
       startTime_ = 0L;
       host_ = "";
       hostURL_ = "";
+      appVersion_ = "";
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -845,6 +909,10 @@ public final class Messages {
         memoizedIsInitialized = 0;
         return false;
       }
+      if (!hasAppVersion()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -894,6 +962,9 @@ public final class Messages {
       if (((bitField0_ & 0x00000800) == 0x00000800)) {
         output.writeBytes(15, getHostURLBytes());
       }
+      if (((bitField0_ & 0x00001000) == 0x00001000)) {
+        output.writeBytes(16, getAppVersionBytes());
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -969,6 +1040,10 @@ public final class Messages {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(15, getHostURLBytes());
       }
+      if (((bitField0_ & 0x00001000) == 0x00001000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(16, getAppVersionBytes());
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -1056,6 +1131,11 @@ public final class Messages {
         result = result && getHostURL()
             .equals(other.getHostURL());
       }
+      result = result && (hasAppVersion() == other.hasAppVersion());
+      if (hasAppVersion()) {
+        result = result && getAppVersion()
+            .equals(other.getAppVersion());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1125,6 +1205,10 @@ public final class Messages {
         hash = (37 * hash) + HOSTURL_FIELD_NUMBER;
         hash = (53 * hash) + getHostURL().hashCode();
       }
+      if (hasAppVersion()) {
+        hash = (37 * hash) + APPVERSION_FIELD_NUMBER;
+        hash = (53 * hash) + getAppVersion().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -1262,6 +1346,8 @@ public final class Messages {
         bitField0_ = (bitField0_ & ~0x00001000);
         hostURL_ = "";
         bitField0_ = (bitField0_ & ~0x00002000);
+        appVersion_ = "";
+        bitField0_ = (bitField0_ & ~0x00004000);
         return this;
       }
 
@@ -1350,6 +1436,10 @@ public final class Messages {
           to_bitField0_ |= 0x00000800;
         }
         result.hostURL_ = hostURL_;
+        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
+          to_bitField0_ |= 0x00001000;
+        }
+        result.appVersion_ = appVersion_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1434,6 +1524,11 @@ public final class Messages {
           hostURL_ = other.hostURL_;
           onChanged();
         }
+        if (other.hasAppVersion()) {
+          bitField0_ |= 0x00004000;
+          appVersion_ = other.appVersion_;
+          onChanged();
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -1475,6 +1570,10 @@ public final class Messages {
           
           return false;
         }
+        if (!hasAppVersion()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -2325,6 +2424,80 @@ public final class Messages {
         return this;
       }
 
+      // required string appVersion = 16;
+      private java.lang.Object appVersion_ = "";
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public boolean hasAppVersion() {
+        return ((bitField0_ & 0x00004000) == 0x00004000);
+      }
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public java.lang.String getAppVersion() {
+        java.lang.Object ref = appVersion_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          appVersion_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public com.google.protobuf.ByteString
+          getAppVersionBytes() {
+        java.lang.Object ref = appVersion_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          appVersion_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public Builder setAppVersion(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00004000;
+        appVersion_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public Builder clearAppVersion() {
+        bitField0_ = (bitField0_ & ~0x00004000);
+        appVersion_ = getDefaultInstance().getAppVersion();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string appVersion = 16;</code>
+       */
+      public Builder setAppVersionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00004000;
+        appVersion_ = value;
+        onChanged();
+        return this;
+      }
+
       // 
@@protoc_insertion_point(builder_scope:org.apache.slider.api.RoleInstanceState)
     }
 
@@ -3816,7 +3989,7 @@ public final class Messages {
    *
    * <pre>
    **
-   * stop the cluster
+   * flex the cluster
    * </pre>
    */
   public static final class FlexClusterResponseProto extends
@@ -4084,7 +4257,7 @@ public final class Messages {
      *
      * <pre>
      **
-     * stop the cluster
+     * flex the cluster
      * </pre>
      */
     public static final class Builder extends
@@ -15453,6 +15626,21 @@ public final class Messages {
      */
     com.google.protobuf.ByteString
         getPlacementBytes();
+
+    // optional string appVersion = 13;
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    boolean hasAppVersion();
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    java.lang.String getAppVersion();
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    com.google.protobuf.ByteString
+        getAppVersionBytes();
   }
   /**
    * Protobuf type {@code org.apache.slider.api.ContainerInformationProto}
@@ -15573,6 +15761,11 @@ public final class Messages {
               placement_ = input.readBytes();
               break;
             }
+            case 106: {
+              bitField0_ |= 0x00000800;
+              appVersion_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -15984,6 +16177,49 @@ public final class Messages {
       }
     }
 
+    // optional string appVersion = 13;
+    public static final int APPVERSION_FIELD_NUMBER = 13;
+    private java.lang.Object appVersion_;
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    public boolean hasAppVersion() {
+      return ((bitField0_ & 0x00000800) == 0x00000800);
+    }
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    public java.lang.String getAppVersion() {
+      java.lang.Object ref = appVersion_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          appVersion_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string appVersion = 13;</code>
+     */
+    public com.google.protobuf.ByteString
+        getAppVersionBytes() {
+      java.lang.Object ref = appVersion_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        appVersion_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
     private void initFields() {
       containerId_ = "";
       component_ = "";
@@ -15997,6 +16233,7 @@ public final class Messages {
       host_ = "";
       hostURL_ = "";
       placement_ = "";
+      appVersion_ = "";
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -16046,6 +16283,9 @@ public final class Messages {
       if (((bitField0_ & 0x00000400) == 0x00000400)) {
         output.writeBytes(12, getPlacementBytes());
       }
+      if (((bitField0_ & 0x00000800) == 0x00000800)) {
+        output.writeBytes(13, getAppVersionBytes());
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -16108,6 +16348,10 @@ public final class Messages {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(12, getPlacementBytes());
       }
+      if (((bitField0_ & 0x00000800) == 0x00000800)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(13, getAppVersionBytes());
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -16188,6 +16432,11 @@ public final class Messages {
         result = result && getPlacement()
             .equals(other.getPlacement());
       }
+      result = result && (hasAppVersion() == other.hasAppVersion());
+      if (hasAppVersion()) {
+        result = result && getAppVersion()
+            .equals(other.getAppVersion());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -16249,6 +16498,10 @@ public final class Messages {
         hash = (37 * hash) + PLACEMENT_FIELD_NUMBER;
         hash = (53 * hash) + getPlacement().hashCode();
       }
+      if (hasAppVersion()) {
+        hash = (37 * hash) + APPVERSION_FIELD_NUMBER;
+        hash = (53 * hash) + getAppVersion().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -16387,6 +16640,8 @@ public final class Messages {
         bitField0_ = (bitField0_ & ~0x00000400);
         placement_ = "";
         bitField0_ = (bitField0_ & ~0x00000800);
+        appVersion_ = "";
+        bitField0_ = (bitField0_ & ~0x00001000);
         return this;
       }
 
@@ -16465,6 +16720,10 @@ public final class Messages {
           to_bitField0_ |= 0x00000400;
         }
         result.placement_ = placement_;
+        if (((from_bitField0_ & 0x00001000) == 0x00001000)) {
+          to_bitField0_ |= 0x00000800;
+        }
+        result.appVersion_ = appVersion_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -16536,6 +16795,11 @@ public final class Messages {
           placement_ = other.placement_;
           onChanged();
         }
+        if (other.hasAppVersion()) {
+          bitField0_ |= 0x00001000;
+          appVersion_ = other.appVersion_;
+          onChanged();
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -17265,6 +17529,80 @@ public final class Messages {
         return this;
       }
 
+      // optional string appVersion = 13;
+      private java.lang.Object appVersion_ = "";
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public boolean hasAppVersion() {
+        return ((bitField0_ & 0x00001000) == 0x00001000);
+      }
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public java.lang.String getAppVersion() {
+        java.lang.Object ref = appVersion_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          appVersion_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public com.google.protobuf.ByteString
+          getAppVersionBytes() {
+        java.lang.Object ref = appVersion_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          appVersion_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public Builder setAppVersion(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00001000;
+        appVersion_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public Builder clearAppVersion() {
+        bitField0_ = (bitField0_ & ~0x00001000);
+        appVersion_ = getDefaultInstance().getAppVersion();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string appVersion = 13;</code>
+       */
+      public Builder setAppVersionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00001000;
+        appVersion_ = value;
+        onChanged();
+        return this;
+      }
+
       // 
@@protoc_insertion_point(builder_scope:org.apache.slider.api.ContainerInformationProto)
     }
 
@@ -26992,55 +27330,56 @@ public final class Messages {
   static {
     java.lang.String[] descriptorData = {
       "\n\033SliderClusterMessages.proto\022\025org.apach" +
-      "e.slider.api\"\203\002\n\021RoleInstanceState\022\014\n\004na" +
+      "e.slider.api\"\227\002\n\021RoleInstanceState\022\014\n\004na" +
       "me\030\001 \002(\t\022\014\n\004role\030\002 
\001(\t\022\r\n\005state\030\004 \002(\r\022\020\n" +
       "\010exitCode\030\005 \002(\r\022\017\n\007command\030\006 
\001(\t\022\023\n\013diag" +
       "nostics\030\007 \001(\t\022\016\n\006output\030\010 
\003(\t\022\023\n\013environ" +
       "ment\030\t \003(\t\022\016\n\006roleId\030\n 
\002(\r\022\020\n\010released\030\013" +
       " \002(\010\022\022\n\ncreateTime\030\014 
\002(\003\022\021\n\tstartTime\030\r " +
-      "\002(\003\022\014\n\004host\030\016 
\002(\t\022\017\n\007hostURL\030\017 \002(\t\"*\n\027St" +
-      "opClusterRequestProto\022\017\n\007message\030\001 \002(\t\"\032" +
-      "\n\030StopClusterResponseProto\".\n\027FlexCluste",
-      "rRequestProto\022\023\n\013clusterSpec\030\001 \002(\t\",\n\030Fl" +
-      "exClusterResponseProto\022\020\n\010response\030\001 \002(\010" +
-      "\"\"\n GetJSONClusterStatusRequestProto\"8\n!" +
-      "GetJSONClusterStatusResponseProto\022\023\n\013clu" +
-      "sterSpec\030\001 \002(\t\"/\n\037ListNodeUUIDsByRoleReq" +
-      "uestProto\022\014\n\004role\030\001 \002(\t\"0\n ListNodeUUIDs" +
-      "ByRoleResponseProto\022\014\n\004uuid\030\001 \003(\t\"#\n\023Get" +
-      "NodeRequestProto\022\014\n\004uuid\030\001 \002(\t\"U\n\024GetNod" +
-      "eResponseProto\022=\n\013clusterNode\030\001 \002(\0132(.or" +
-      "g.apache.slider.api.RoleInstanceState\"+\n",
-      "\033GetClusterNodesRequestProto\022\014\n\004uuid\030\001 \003" +
-      "(\t\"]\n\034GetClusterNodesResponseProto\022=\n\013cl" +
-      "usterNode\030\001 \003(\0132(.org.apache.slider.api." +
-      "RoleInstanceState\" \n\020EchoRequestProto\022\014\n" +
-      "\004text\030\001 \002(\t\"!\n\021EchoResponseProto\022\014\n\004text" +
-      "\030\001 \002(\t\"\'\n\031KillContainerRequestProto\022\n\n\002i" +
-      "d\030\001 \002(\t\"-\n\032KillContainerResponseProto\022\017\n" +
-      "\007success\030\001 \002(\010\"D\n\025AMSuicideRequestProto\022" +
-      "\014\n\004text\030\001 \002(\t\022\016\n\006signal\030\002 
\002(\005\022\r\n\005delay\030\003" +
-      " \002(\005\"\030\n\026AMSuicideResponseProto\"#\n!GetIns",
-      "tanceDefinitionRequestProto\"^\n\"GetInstan" +
-      "ceDefinitionResponseProto\022\020\n\010internal\030\001 " +
-      "\002(\t\022\021\n\tresources\030\002 
\002(\t\022\023\n\013application\030\003 " +
-      "\002(\t\"`\n#ApplicationLivenessInformationPro" +
-      "to\022\034\n\024allRequestsSatisfied\030\001 
\001(\010\022\033\n\023requ" +
-      "estsOutstanding\030\002 \001(\005\"\250\002\n\031ComponentInfor" +
-      "mationProto\022\014\n\004name\030\001 
\001(\t\022\020\n\010priority\030\002 " +
-      "\001(\005\022\017\n\007desired\030\003 
\001(\005\022\016\n\006actual\030\004 \001(\005\022\021\n\t" +
-      "releasing\030\005 \001(\005\022\021\n\trequested\030\006 
\001(\005\022\016\n\006fa" +
-      "iled\030\007 \001(\005\022\017\n\007started\030\010 
\001(\005\022\023\n\013startFail",
-      "ed\030\t \001(\005\022\021\n\tcompleted\030\n 
\001(\005\022\026\n\016totalRequ" +
-      "ested\030\013 \001(\005\022\026\n\016failureMessage\030\014 
\001(\t\022\027\n\017p" +
-      "lacementPolicy\030\r \001(\005\022\022\n\ncontainers\030\016 \003(\t" +
-      "\"\364\001\n\031ContainerInformationProto\022\023\n\013contai" +
-      "nerId\030\001 \001(\t\022\021\n\tcomponent\030\002 
\001(\t\022\020\n\010releas" +
-      "ed\030\003 \001(\010\022\r\n\005state\030\004 
\001(\005\022\020\n\010exitCode\030\005 \001(" +
-      "\005\022\023\n\013diagnostics\030\006 
\001(\t\022\022\n\ncreateTime\030\007 \001" +
-      "(\003\022\021\n\tstartTime\030\010 \001(\003\022\016\n\006output\030\t 
\003(\t\022\014\n" +
-      "\004host\030\n \001(\t\022\017\n\007hostURL\030\013 
\001(\t\022\021\n\tplacemen" +
-      "t\030\014 \001(\t\"N\n\024PingInformationProto\022\014\n\004text\030",
+      "\002(\003\022\014\n\004host\030\016 
\002(\t\022\017\n\007hostURL\030\017 \002(\t\022\022\n\nap" +
+      "pVersion\030\020 \002(\t\"*\n\027StopClusterRequestProt" +
+      "o\022\017\n\007message\030\001 \002(\t\"\032\n\030StopClusterRespons",
+      "eProto\".\n\027FlexClusterRequestProto\022\023\n\013clu" +
+      "sterSpec\030\001 \002(\t\",\n\030FlexClusterResponsePro" +
+      "to\022\020\n\010response\030\001 \002(\010\"\"\n GetJSONClusterSt" +
+      "atusRequestProto\"8\n!GetJSONClusterStatus" +
+      "ResponseProto\022\023\n\013clusterSpec\030\001 \002(\t\"/\n\037Li" +
+      "stNodeUUIDsByRoleRequestProto\022\014\n\004role\030\001 " +
+      "\002(\t\"0\n ListNodeUUIDsByRoleResponseProto\022" +
+      "\014\n\004uuid\030\001 
\003(\t\"#\n\023GetNodeRequestProto\022\014\n\004" +
+      "uuid\030\001 \002(\t\"U\n\024GetNodeResponseProto\022=\n\013cl" +
+      "usterNode\030\001 \002(\0132(.org.apache.slider.api.",
+      "RoleInstanceState\"+\n\033GetClusterNodesRequ" +
+      "estProto\022\014\n\004uuid\030\001 \003(\t\"]\n\034GetClusterNode" +
+      "sResponseProto\022=\n\013clusterNode\030\001 \003(\0132(.or" +
+      "g.apache.slider.api.RoleInstanceState\" \n" +
+      "\020EchoRequestProto\022\014\n\004text\030\001 \002(\t\"!\n\021EchoR" +
+      "esponseProto\022\014\n\004text\030\001 \002(\t\"\'\n\031KillContai" +
+      "nerRequestProto\022\n\n\002id\030\001 \002(\t\"-\n\032KillConta" +
+      "inerResponseProto\022\017\n\007success\030\001 \002(\010\"D\n\025AM" +
+      "SuicideRequestProto\022\014\n\004text\030\001 \002(\t\022\016\n\006sig" 
+
+      "nal\030\002 \002(\005\022\r\n\005delay\030\003 
\002(\005\"\030\n\026AMSuicideRes",
+      "ponseProto\"#\n!GetInstanceDefinitionReque" +
+      "stProto\"^\n\"GetInstanceDefinitionResponse" +
+      "Proto\022\020\n\010internal\030\001 
\002(\t\022\021\n\tresources\030\002 \002" +
+      "(\t\022\023\n\013application\030\003 \002(\t\"`\n#ApplicationLi" +
+      "venessInformationProto\022\034\n\024allRequestsSat" +
+      "isfied\030\001 \001(\010\022\033\n\023requestsOutstanding\030\002 
\001(" +
+      "\005\"\250\002\n\031ComponentInformationProto\022\014\n\004name\030" +
+      "\001 \001(\t\022\020\n\010priority\030\002 
\001(\005\022\017\n\007desired\030\003 \001(\005" +
+      "\022\016\n\006actual\030\004 \001(\005\022\021\n\treleasing\030\005 
\001(\005\022\021\n\tr" +
+      "equested\030\006 \001(\005\022\016\n\006failed\030\007 
\001(\005\022\017\n\007starte",
+      "d\030\010 \001(\005\022\023\n\013startFailed\030\t 
\001(\005\022\021\n\tcomplete" +
+      "d\030\n \001(\005\022\026\n\016totalRequested\030\013 
\001(\005\022\026\n\016failu" +
+      "reMessage\030\014 \001(\t\022\027\n\017placementPolicy\030\r \001(\005" 
+
+      "\022\022\n\ncontainers\030\016 \003(\t\"\210\002\n\031ContainerInform" +
+      "ationProto\022\023\n\013containerId\030\001 \001(\t\022\021\n\tcompo" +
+      "nent\030\002 \001(\t\022\020\n\010released\030\003 
\001(\010\022\r\n\005state\030\004 " +
+      "\001(\005\022\020\n\010exitCode\030\005 
\001(\005\022\023\n\013diagnostics\030\006 \001" +
+      "(\t\022\022\n\ncreateTime\030\007 
\001(\003\022\021\n\tstartTime\030\010 \001(" +
+      "\003\022\016\n\006output\030\t \003(\t\022\014\n\004host\030\n 
\001(\t\022\017\n\007hostU" +
+      "RL\030\013 \001(\t\022\021\n\tplacement\030\014 
\001(\t\022\022\n\nappVersio",
+      "n\030\r \001(\t\"N\n\024PingInformationProto\022\014\n\004text\030" +
       "\001 \001(\t\022\014\n\004verb\030\002 
\001(\t\022\014\n\004body\030\003 \001(\t\022\014\n\004tim" +
       "e\030\004 \001(\003\"\026\n\024GetModelRequestProto\"\035\n\033GetMo" +
       "delDesiredRequestProto\"$\n\"GetModelDesire" +
@@ -27049,8 +27388,8 @@ public final class Messages {
       "AppconfRequestProto\"\'\n%GetModelResolvedR" +
       "esourcesRequestProto\"#\n!GetModelLiveReso" +
       "urcesRequestProto\"\037\n\035GetLiveContainersRe" +
-      "questProto\"u\n\036GetLiveContainersResponseP" +
-      "roto\022\r\n\005names\030\001 \003(\t\022D\n\ncontainers\030\002 
\003(\0132",
+      "questProto\"u\n\036GetLiveContainersResponseP",
+      "roto\022\r\n\005names\030\001 \003(\t\022D\n\ncontainers\030\002 
\003(\0132" +
       "0.org.apache.slider.api.ContainerInforma" +
       "tionProto\"3\n\034GetLiveContainerRequestProt" +
       "o\022\023\n\013containerId\030\001 \002(\t\"\037\n\035GetLiveCompone" +
@@ -27059,8 +27398,8 @@ public final class Messages {
       " \003(\01320.org.apache.slider.api.ComponentIn" +
       "formationProto\",\n\034GetLiveComponentReques" +
       "tProto\022\014\n\004name\030\001 \002(\t\"$\n\"GetApplicationLi" +
-      "venessRequestProto\"\023\n\021EmptyPayloadProto\"" +
-      " \n\020WrappedJsonProto\022\014\n\004json\030\001 \002(\t\"h\n\037Get",
+      "venessRequestProto\"\023\n\021EmptyPayloadProto\"",
+      " \n\020WrappedJsonProto\022\014\n\004json\030\001 \002(\t\"h\n\037Get" +
       "CertificateStoreRequestProto\022\020\n\010hostname" +
       "\030\001 \001(\t\022\023\n\013requesterId\030\002 
\002(\t\022\020\n\010password\030" +
       "\003 \002(\t\022\014\n\004type\030\004 \002(\t\"1\n GetCertificateSto" +
@@ -27077,7 +27416,7 @@ public final class Messages {
           
internal_static_org_apache_slider_api_RoleInstanceState_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               
internal_static_org_apache_slider_api_RoleInstanceState_descriptor,
-              new java.lang.String[] { "Name", "Role", "State", "ExitCode", 
"Command", "Diagnostics", "Output", "Environment", "RoleId", "Released", 
"CreateTime", "StartTime", "Host", "HostURL", });
+              new java.lang.String[] { "Name", "Role", "State", "ExitCode", 
"Command", "Diagnostics", "Output", "Environment", "RoleId", "Released", 
"CreateTime", "StartTime", "Host", "HostURL", "AppVersion", });
           
internal_static_org_apache_slider_api_StopClusterRequestProto_descriptor =
             getDescriptor().getMessageTypes().get(1);
           
internal_static_org_apache_slider_api_StopClusterRequestProto_fieldAccessorTable
 = new
@@ -27215,7 +27554,7 @@ public final class Messages {
           
internal_static_org_apache_slider_api_ContainerInformationProto_fieldAccessorTable
 = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               
internal_static_org_apache_slider_api_ContainerInformationProto_descriptor,
-              new java.lang.String[] { "ContainerId", "Component", "Released", 
"State", "ExitCode", "Diagnostics", "CreateTime", "StartTime", "Output", 
"Host", "HostURL", "Placement", });
+              new java.lang.String[] { "ContainerId", "Component", "Released", 
"State", "ExitCode", "Diagnostics", "CreateTime", "StartTime", "Output", 
"Host", "HostURL", "Placement", "AppVersion", });
           
internal_static_org_apache_slider_api_PingInformationProto_descriptor =
             getDescriptor().getMessageTypes().get(24);
           
internal_static_org_apache_slider_api_PingInformationProto_fieldAccessorTable = 
new

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
 
b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
index 4264582..f005bc3 100644
--- 
a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
+++ 
b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java
@@ -137,6 +137,7 @@ public class RestTypeMarshalling {
     ContainerInformation info = new ContainerInformation();
     info.containerId = wire.getContainerId();
     info.component = wire.getComponent();
+    info.appVersion = wire.getAppVersion();
     info.state = wire.getState();
     if (wire.hasReleased()) {
       info.released = wire.getReleased();
@@ -186,6 +187,9 @@ public class RestTypeMarshalling {
     if (info.component != null) {
       builder.setComponent(info.component);
     }
+    if (info.appVersion != null) {
+      builder.setAppVersion(info.appVersion);
+    }
     builder.setCreateTime(info.createTime);
     if (info.diagnostics != null) {
       builder.setDiagnostics(info.diagnostics);

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/api/types/ContainerInformation.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/api/types/ContainerInformation.java
 
b/slider-core/src/main/java/org/apache/slider/api/types/ContainerInformation.java
index 8c26bfe..6991340 100644
--- 
a/slider-core/src/main/java/org/apache/slider/api/types/ContainerInformation.java
+++ 
b/slider-core/src/main/java/org/apache/slider/api/types/ContainerInformation.java
@@ -31,6 +31,7 @@ public class ContainerInformation {
   
   public String containerId;
   public String component;
+  public String appVersion;
   public Boolean released;
   public int state;
   public Integer exitCode;

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java 
b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index 658fe7f..053a1db 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -917,7 +917,10 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
       }
     }
 
-    Path pkgPath = sliderFileSystem.buildPackageDirPath(installPkgInfo.name);
+    // Do not provide new options to install-package command as it is in
+    // deprecated mode. So version is kept null here. Use package --install.
+    Path pkgPath = sliderFileSystem.buildPackageDirPath(installPkgInfo.name,
+        null);
     sliderFileSystem.getFileSystem().mkdirs(pkgPath);
 
     Path fileInFs = new Path(pkgPath, srcFile.getName());
@@ -1125,13 +1128,14 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
       return EXIT_SUCCESS;
     }
     String pkgPathValue = sliderFileSystem
-        .buildPackageDirPath(StringUtils.EMPTY).toUri().getPath();
+        .buildPackageDirPath(StringUtils.EMPTY, StringUtils.EMPTY).toUri()
+        .getPath();
     FileSystem fs = sliderFileSystem.getFileSystem();
     Iterator<Map.Entry<String, Path>> instanceItr = persistentInstances
         .entrySet().iterator();
     log.info("List of applications with its package name and path");
-    println("%-25s  %15s  %s", "Cluster Name", "Package Name",
-        "Application Location");
+    println("%-25s  %15s  %30s  %s", "Cluster Name", "Package Name",
+        "Package Version", "Application Location");
     while(instanceItr.hasNext()) {
       Map.Entry<String, Path> entry = instanceItr.next();
       String clusterName = entry.getKey();
@@ -1140,8 +1144,9 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
           clusterName, clusterPath);
       Path appDefPath = null;
       try {
-        appDefPath = new Path(instanceDefinition.getAppConfOperations()
-            .getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF));
+        appDefPath = new Path(
+            SliderUtils.getApplicationDefinitionPath(instanceDefinition
+                .getAppConfOperations()));
       } catch (BadConfigException e) {
         // Invalid cluster state, so move on to next. No need to log anything
         // as this is just listing of instances.
@@ -1152,11 +1157,15 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
       }
       String appDefPathStr = appDefPath.toUri().getPath();
       try {
-        if (appDefPathStr.contains(pkgPathValue)
-            && fs.isFile(appDefPath)) {
+        if (appDefPathStr.contains(pkgPathValue) && fs.isFile(appDefPath)) {
           String packageName = appDefPath.getParent().getName();
-          println("%-25s  %15s  %s", clusterName, packageName,
-              appDefPathStr);
+          String packageVersion = StringUtils.EMPTY;
+          if (instanceDefinition.isVersioned()) {
+            packageVersion = packageName;
+            packageName = appDefPath.getParent().getParent().getName();
+          }
+          println("%-25s  %15s  %30s  %s", clusterName, packageName,
+              packageVersion, appDefPathStr);
         }
       } catch(IOException e) {
         if(log.isDebugEnabled()) {
@@ -1169,7 +1178,8 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
   }
 
   private int actionPackageList() throws IOException {
-    Path pkgPath = sliderFileSystem.buildPackageDirPath(StringUtils.EMPTY);
+    Path pkgPath = sliderFileSystem.buildPackageDirPath(StringUtils.EMPTY,
+        StringUtils.EMPTY);
     log.info("Package install path : " + pkgPath);
     if (!sliderFileSystem.getFileSystem().isDirectory(pkgPath)) {
       log.info("No package(s) installed");
@@ -1220,7 +1230,8 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
       }
     }
 
-    Path pkgPath = 
sliderFileSystem.buildPackageDirPath(actionPackageArgs.name);
+    Path pkgPath = sliderFileSystem.buildPackageDirPath(actionPackageArgs.name,
+        actionPackageArgs.version);
     sliderFileSystem.getFileSystem().mkdirs(pkgPath);
 
     Path fileInFs = new Path(pkgPath, srcFile.getName());
@@ -1246,7 +1257,8 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
               + CommonArgs.usage(serviceArgs, ACTION_PACKAGE));
     }
 
-    Path pkgPath = 
sliderFileSystem.buildPackageDirPath(actionPackageArgs.name);
+    Path pkgPath = sliderFileSystem.buildPackageDirPath(actionPackageArgs.name,
+        actionPackageArgs.version);
     if (!sliderFileSystem.getFileSystem().exists(pkgPath)) {
       throw new BadCommandArgumentsException("Package does not exists at "
           + pkgPath.toUri().toString());
@@ -1668,7 +1680,7 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
 
     // add the tags if available
     Set<String> applicationTags = provider.getApplicationTags(sliderFileSystem,
-        appOperations.getGlobalOptions().get(AgentKeys.APP_DEF));
+        SliderUtils.getApplicationDefinitionPath(appOperations));
     AppMasterLauncher amLauncher = new AppMasterLauncher(clustername,
         SliderKeys.APP_TYPE,
         config,
@@ -2673,7 +2685,7 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
               new SliderUtils.OnDemandReportStringifier(app));
     if (app.getYarnApplicationState().ordinal() >=
         YarnApplicationState.FINISHED.ordinal()) {
-      log.info("Cluster {} is a terminated state {}", clustername,
+      log.info("Cluster {} is in a terminated state {}", clustername,
                app.getYarnApplicationState());
       return EXIT_SUCCESS;
     }
@@ -3285,8 +3297,9 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
         log.error("can not open agent package: " + e.toString());
         return;
       }
-      String pkgTarballPath = instanceDefinition.getAppConfOperations()
-          .getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
+      String pkgTarballPath = SliderUtils
+          .getApplicationDefinitionPath(instanceDefinition
+              .getAppConfOperations());
       try {
         SliderUtils.validateHDFSFile(sliderFileSystem, pkgTarballPath);
         log.info("Application package is properly installed");
@@ -3431,8 +3444,8 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
     }
     String clusterDir = instanceDefinition.getAppConfOperations()
         .getGlobalOptions().get(AgentKeys.APP_ROOT);
-    String pkgTarball = instanceDefinition.getAppConfOperations()
-        .getGlobalOptions().get(AgentKeys.APP_DEF);
+    String pkgTarball = SliderUtils
+        
.getApplicationDefinitionPath(instanceDefinition.getAppConfOperations());
     String runAsUser = instanceDefinition.getAppConfOperations()
         .getGlobalOptions().get(AgentKeys.RUNAS_USER);
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java 
b/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
index 30ff258..56ea022 100644
--- a/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/common/SliderKeys.java
@@ -55,6 +55,11 @@ public interface SliderKeys extends SliderXmlConfKeys {
   String APP_TYPE = "org-apache-slider";
 
   /**
+   * Key for application version. This must be set in app_config/global 
{@value}
+   */
+  String APP_VERSION = "site.global.app_version";
+
+  /**
    * JVM arg to force IPv4  {@value}
    */
   String JVM_ENABLE_ASSERTIONS = "-ea";

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/common/params/ActionPackageArgs.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/params/ActionPackageArgs.java
 
b/slider-core/src/main/java/org/apache/slider/common/params/ActionPackageArgs.java
index 0ea7351..feae7eb 100644
--- 
a/slider-core/src/main/java/org/apache/slider/common/params/ActionPackageArgs.java
+++ 
b/slider-core/src/main/java/org/apache/slider/common/params/ActionPackageArgs.java
@@ -55,6 +55,9 @@ public class ActionPackageArgs extends AbstractActionArgs {
              description = "Package name")
   public String name;
 
+  @Parameter(names = {ARG_VERSION}, description = "Package version")
+  public String version;
+
   @Parameter(names = {ARG_REPLACE_PKG}, description = "Overwrite existing 
package")
   public boolean replacePkg = false;
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java 
b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
index ea393d5..d19222a 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
@@ -78,6 +78,7 @@ public interface Arguments {
   String ARG_MANAGER_SHORT = "--m";
   String ARG_MESSAGE = "--message";
   String ARG_NAME = "--name";
+  String ARG_VERSION = "--version";
   String ARG_OPTION = "--option";
   String ARG_OPTION_SHORT = "-O";
   String ARG_OUTPUT = "--out";

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java 
b/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
index 3df73df..c290e0f 100644
--- 
a/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
+++ 
b/slider-core/src/main/java/org/apache/slider/common/tools/CoreFileSystem.java
@@ -19,6 +19,8 @@
 package org.apache.slider.common.tools;
 
 import com.google.common.base.Preconditions;
+
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeys;
 import org.apache.hadoop.fs.FSDataOutputStream;
@@ -152,10 +154,14 @@ public class CoreFileSystem {
    *
    * @return the path for persistent app package
    */
-  public Path buildPackageDirPath(String packageName) {
+  public Path buildPackageDirPath(String packageName, String packageVersion) {
     Preconditions.checkNotNull(packageName);
     Path path = getBaseApplicationPath();
-    return new Path(path, SliderKeys.PACKAGE_DIRECTORY + "/" + packageName);
+    path = new Path(path, SliderKeys.PACKAGE_DIRECTORY + "/" + packageName);
+    if (StringUtils.isNotEmpty(packageVersion)) {
+      path = new Path(path, packageVersion);
+    }
+    return path;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java 
b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
index 74f33dc..f7c843c 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
@@ -53,6 +53,7 @@ import org.apache.slider.api.RoleKeys;
 import org.apache.slider.api.types.ContainerInformation;
 import org.apache.slider.common.SliderKeys;
 import org.apache.slider.common.SliderXmlConfKeys;
+import org.apache.slider.core.conf.ConfTreeOperations;
 import org.apache.slider.core.conf.MapOperations;
 import org.apache.slider.core.exceptions.BadClusterStateException;
 import org.apache.slider.core.exceptions.BadCommandArgumentsException;
@@ -61,6 +62,7 @@ import org.apache.slider.core.exceptions.ErrorStrings;
 import org.apache.slider.core.exceptions.SliderException;
 import org.apache.slider.core.launch.ClasspathConstructor;
 import org.apache.slider.core.main.LauncherExitCodes;
+import org.apache.slider.providers.agent.AgentKeys;
 import org.apache.slider.server.services.utility.PatternValidator;
 import org.apache.slider.server.services.workflow.ForkedProcessService;
 import org.apache.zookeeper.server.util.KerberosUtil;
@@ -691,7 +693,7 @@ public final class SliderUtils {
       }
       if (containers != null) {
         builder.append('\n');
-        builder.append(SliderUtils.addContainersToString(containers));
+        builder.append(SliderUtils.containersToString(containers));
       }
     }
 
@@ -699,14 +701,14 @@ public final class SliderUtils {
     return builder.toString();
   }
 
-  public static String addContainersToString(
+  public static String containersToString(
       List<ContainerInformation> containers) {
-    String containerf = "  %-40s  %40s  %-30s\n";
+    String containerf = "  %-28s  %30s  %40s  %s\n";
     StringBuilder builder = new StringBuilder(512);
     builder.append("Containers:\n");
     for (ContainerInformation container : containers) {
       builder.append(String.format(containerf, container.component,
-          container.containerId, container.host));
+          container.appVersion, container.containerId, container.host));
     }
     return builder.toString();
   }
@@ -2145,6 +2147,20 @@ public final class SliderUtils {
   }
 
   /**
+   * return the HDFS path where the application package has been uploaded
+   * manually or by using slider client (install package command)
+   * 
+   * @param conf configuration
+   * @return
+   */
+  public static String getApplicationDefinitionPath(ConfTreeOperations conf)
+      throws BadConfigException {
+    String appDefPath = conf.getGlobalOptions().getMandatoryOption(
+        AgentKeys.APP_DEF);
+    return appDefPath;
+  }
+
+  /**
    * return the path to the slider-client.xml used by the current running
    * slider command
    *

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/core/conf/AggregateConf.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/core/conf/AggregateConf.java 
b/slider-core/src/main/java/org/apache/slider/core/conf/AggregateConf.java
index 103d44b..18c3156 100644
--- a/slider-core/src/main/java/org/apache/slider/core/conf/AggregateConf.java
+++ b/slider-core/src/main/java/org/apache/slider/core/conf/AggregateConf.java
@@ -19,6 +19,7 @@
 package org.apache.slider.core.conf;
 
 import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.slider.common.SliderKeys;
 import org.apache.slider.core.exceptions.BadConfigException;
 import org.codehaus.jackson.annotate.JsonIgnore;
@@ -169,6 +170,18 @@ public final class AggregateConf {
   }
 
   /**
+   * Is this app package versioned?
+   * 
+   * @return true if {@link SliderKeys#APP_VERSION} was set in the app config
+   *         provided during creation of this app
+   * @since 0.80.0-incubating
+   */
+  public boolean isVersioned() {
+    return StringUtils.isNotEmpty(getAppConfOperations().getGlobalOptions()
+        .get(SliderKeys.APP_VERSION));
+  }
+
+  /**
    * string operation includes all the inner conftrees
    * @return a string description
    */

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/providers/agent/AgentClientProvider.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentClientProvider.java
 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentClientProvider.java
index 2e981c6..ed453ec 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentClientProvider.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentClientProvider.java
@@ -114,8 +114,8 @@ public class AgentClientProvider extends 
AbstractClientProvider
                                                 clusterDirPath,
                                                 generatedConfDirPath, secure);
 
-    String appDef = instanceDefinition.getAppConfOperations().
-        getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
+    String appDef = SliderUtils.getApplicationDefinitionPath(instanceDefinition
+        .getAppConfOperations());
     Path appDefPath = new Path(appDef);
     sliderFileSystem.verifyFileExists(appDefPath);
 
@@ -145,16 +145,16 @@ public class AgentClientProvider extends 
AbstractClientProvider
     providerUtils.validateNodeCount(instanceDefinition, ROLE_NODE,
                                     0, -1);
 
+    String appDef = null;
     try {
       // Validate the app definition
-      instanceDefinition.getAppConfOperations().
-          getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
+      // Validate the app definition
+      appDef = SliderUtils.getApplicationDefinitionPath(instanceDefinition
+          .getAppConfOperations());
     } catch (BadConfigException bce) {
       throw new BadConfigException("Application definition must be provided. " 
+ bce.getMessage());
     }
 
-    String appDef = instanceDefinition.getAppConfOperations().
-        getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
     log.info("Validating app definition {}", appDef);
     String extension = appDef.substring(appDef.lastIndexOf(".") + 1, 
appDef.length());
     if (!"zip".equals(extension.toLowerCase(Locale.ENGLISH))) {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
index 4b5f582..d95230f 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
@@ -260,8 +260,8 @@ public class AgentProviderService extends 
AbstractProviderService implements
   // Reads the metainfo.xml in the application package and loads it
   private void buildMetainfo(AggregateConf instanceDefinition,
                              SliderFileSystem fileSystem) throws IOException, 
SliderException {
-    String appDef = instanceDefinition.getAppConfOperations()
-        .getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
+    String appDef = SliderUtils.getApplicationDefinitionPath(instanceDefinition
+        .getAppConfOperations());
 
     if (metaInfo == null) {
       synchronized (syncLock) {
@@ -304,8 +304,8 @@ public class AgentProviderService extends 
AbstractProviderService implements
       IOException,
       SliderException {
 
-    String appDef = instanceDefinition.getAppConfOperations().
-        getGlobalOptions().getMandatoryOption(AgentKeys.APP_DEF);
+    String appDef = SliderUtils.getApplicationDefinitionPath(instanceDefinition
+        .getAppConfOperations());
 
     initializeApplicationConfiguration(instanceDefinition, fileSystem);
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/server/appmaster/RoleLaunchService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/RoleLaunchService.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/RoleLaunchService.java
index df65ff4..d4f2fd5 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/RoleLaunchService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/RoleLaunchService.java
@@ -23,6 +23,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.yarn.api.records.Container;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.slider.common.SliderKeys;
 import org.apache.slider.common.tools.SliderFileSystem;
 import org.apache.slider.core.conf.AggregateConf;
 import org.apache.slider.core.conf.MapOperations;
@@ -217,6 +218,8 @@ public class RoleLaunchService
         instance.command = commandsAsString;
         instance.role = containerRole;
         instance.roleId = role.id;
+        instance.appVersion = instanceDefinition.getAppConfOperations()
+            .getGlobalOptions().get(SliderKeys.APP_VERSION);
         instance.environment = envDescription;
         int delay = appComponent.getOptionInt(
             AgentKeys.KEY_CONTAINER_LAUNCH_DELAY, 0);

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index b8584f7..8a52043 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -1553,7 +1553,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
    * Callback event when a container is allocated.
    * 
    * The app state is updated with the allocation, and builds up a list
-   * of assignments and RM opreations. The assignments are 
+   * of assignments and RM operations. The assignments are 
    * handed off into the pool of service launchers to asynchronously schedule
    * container launch operations.
    * 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleInstance.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleInstance.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleInstance.java
index 726ee08..4b7cfb6 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleInstance.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleInstance.java
@@ -58,6 +58,11 @@ public final class RoleInstance implements Cloneable {
   public String role;
 
   /**
+   * Version of the app
+   */
+  public String appVersion;
+
+  /**
    * Role Id; matches priority in resources.json
    */
   public int roleId;
@@ -200,6 +205,7 @@ public final class RoleInstance implements Cloneable {
     builder.setStartTime(startTime);
     builder.setHost(host);
     builder.setHostURL(hostURL);
+    builder.setAppVersion(appVersion);
     return builder.build();
   }
 
@@ -291,6 +297,7 @@ public final class RoleInstance implements Cloneable {
     ContainerInformation info = new ContainerInformation();
     info.containerId = id;
     info.component = role;
+    info.appVersion = appVersion;
     info.startTime = startTime;
     info.createTime = createTime;
     info.diagnostics = diagnostics;

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/main/proto/SliderClusterMessages.proto
----------------------------------------------------------------------
diff --git a/slider-core/src/main/proto/SliderClusterMessages.proto 
b/slider-core/src/main/proto/SliderClusterMessages.proto
index 730a49b..c0350e5 100644
--- a/slider-core/src/main/proto/SliderClusterMessages.proto
+++ b/slider-core/src/main/proto/SliderClusterMessages.proto
@@ -39,6 +39,7 @@ message RoleInstanceState {
   required int64 startTime = 13;
   required string host = 14;
   required string hostURL = 15;
+  required string appVersion = 16;
 }
 
 /**
@@ -65,7 +66,7 @@ message FlexClusterRequestProto {
 
 
 /**
- * stop the cluster
+ * flex the cluster
  */
 message FlexClusterResponseProto {
   required bool response = 1;
@@ -245,6 +246,7 @@ message ContainerInformationProto {
   optional string host = 10;
   optional string hostURL = 11;
   optional string placement = 12;
+  optional string appVersion = 13;
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3021a04/slider-core/src/test/groovy/org/apache/slider/agent/actions/TestActionList.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/actions/TestActionList.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/actions/TestActionList.groovy
index 15ad701..4d27c37 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/actions/TestActionList.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/actions/TestActionList.groovy
@@ -18,20 +18,33 @@
 
 package org.apache.slider.agent.actions
 
+import java.io.IOException;
+
 import groovy.util.logging.Slf4j
+import org.apache.hadoop.fs.FileSystem
+import org.apache.hadoop.fs.Path
+import org.apache.hadoop.fs.RawLocalFileSystem
 import org.apache.hadoop.yarn.api.records.ApplicationId
 import org.apache.hadoop.yarn.api.records.ApplicationReport
 import org.apache.hadoop.yarn.api.records.YarnApplicationState
 import org.apache.hadoop.yarn.conf.YarnConfiguration
+
 import org.apache.slider.agent.AgentMiniClusterTestBase
 import org.apache.slider.client.SliderClient
+import org.apache.slider.common.SliderKeys
 import org.apache.slider.common.params.ActionListArgs
 import org.apache.slider.common.params.ActionThawArgs
 import org.apache.slider.common.params.Arguments
+import org.apache.slider.common.params.ClientArgs
 import org.apache.slider.common.params.SliderActions
+import org.apache.slider.common.tools.SliderFileSystem;
+import org.apache.slider.common.tools.SliderUtils
 import org.apache.slider.core.exceptions.BadCommandArgumentsException
+import org.apache.slider.core.exceptions.SliderException;
 import org.apache.slider.core.exceptions.UnknownApplicationInstanceException
 import org.apache.slider.core.main.ServiceLauncher
+import org.apache.slider.providers.agent.AgentKeys
+
 import org.junit.Before
 import org.junit.Test
 
@@ -40,10 +53,17 @@ import org.junit.Test
  */
 @Slf4j
 class TestActionList extends AgentMiniClusterTestBase {
+  private static SliderFileSystem testFileSystem
+  private static String APP_NAME = "HBASE"
+  private static String APP_VERSION = "1.0.0"
 
   @Before
   public void setup() {
     super.setup()
+    FileSystem fileSystem = new RawLocalFileSystem()
+    YarnConfiguration configuration = SliderUtils.createConfiguration()
+    fileSystem.setConf(configuration)
+    testFileSystem = new SliderFileSystem(fileSystem, configuration)
     createMiniCluster("", configuration, 1, true)
   }
 
@@ -58,6 +78,7 @@ class TestActionList extends AgentMiniClusterTestBase {
     testListThisUserNoClusters()
     testListMissingCluster()
     testActionList()
+    testActionListWithContainers()
   }
 
   public void testActionList() {
@@ -228,7 +249,79 @@ class TestActionList extends AgentMiniClusterTestBase {
         YarnApplicationState.RUNNING, YarnApplicationState.RUNNING).size()
   }
 
+  public void testActionListWithContainers() {
+    YarnConfiguration yarnConfig = new YarnConfiguration(configuration)
+    String clustername = "testactionlistwithcontainers"
+    // get the default application.def file and install it as a package
+    String appDefPath = agentDefOptions.getAt(AgentKeys.APP_DEF)
+    File appDefFile = new File(new URI(appDefPath))
+    YarnConfiguration conf = SliderUtils.createConfiguration()
+    ServiceLauncher<SliderClient> launcher = launch(TestSliderClient,
+        conf,
+        [
+          ClientArgs.ACTION_PACKAGE,
+          ClientArgs.ARG_INSTALL,
+          ClientArgs.ARG_NAME,
+          APP_NAME,
+          ClientArgs.ARG_PACKAGE,
+          appDefFile.absolutePath,
+          ClientArgs.ARG_VERSION,
+          APP_VERSION,
+          ClientArgs.ARG_REPLACE_PKG
+        ])
+    Path installedPath = new Path(testFileSystem.buildPackageDirPath(APP_NAME,
+      APP_VERSION), appDefFile.getName())
+    File installedPackage = new File(installedPath.toUri().path)
+    assert installedPackage.exists()
+    describe("Installed app package to - " + installedPackage.toURI()
+      .toString())
+    // overwrite the application.def property with the new installed path
+    agentDefOptions.putAt(AgentKeys.APP_DEF, installedPackage.toURI()
+      .toString())
+    // add the app version
+    agentDefOptions.putAt(SliderKeys.APP_VERSION, APP_VERSION)
+    // start the app and AM
+    describe("Starting the app")
+    launcher = createStandaloneAM(clustername, true, false)
+    SliderClient sliderClient = launcher.service
+    addToTeardown(sliderClient)
+    waitForClusterLive(sliderClient)
 
+    describe("Listing all containers of cluster")
+    String outFileName = "target/actionListWithContainers.out"
+    launcher = launchClientAgainstMiniMR(
+        //config includes RM binding info
+        yarnConfig,
+        //varargs list of command line params
+        [SliderActions.ACTION_LIST,
+         clustername,
+         Arguments.ARG_CONTAINERS
+        ]
+    )
+    // reset the app def path to orig value and remove app version
+    agentDefOptions.putAt(AgentKeys.APP_DEF, appDefPath)
+    agentDefOptions.remove(SliderKeys.APP_VERSION)
+
+    assert launcher.serviceExitCode == 0
+    def client = launcher.service
+    def instances = client.enumSliderInstances(false, null, null)
+    assert instances.size() > 0
+    def enumeratedInstance = instances[clustername]
+    assert enumeratedInstance != null
+    assert enumeratedInstance.applicationReport.name ==
+           clustername
+    assert enumeratedInstance.name == clustername
+    assert enumeratedInstance.path.toString().endsWith("/" + clustername)
+    assert enumeratedInstance.applicationReport != null
+    assert enumeratedInstance.applicationReport.yarnApplicationState == 
+      YarnApplicationState.RUNNING
+    instances = sliderClient.enumSliderInstances(true,
+      YarnApplicationState.RUNNING, YarnApplicationState.RUNNING)
+    assert instances[clustername]
+
+    clusterActionFreeze(sliderClient, clustername, "stopping first cluster")
+    waitForAppToFinish(sliderClient)
+  }
 
   public void testListThisUserNoClusters() throws Throwable {
     log.info("RM address = ${RMAddr}")
@@ -243,6 +336,7 @@ class TestActionList extends AgentMiniClusterTestBase {
     )
     assert launcher.serviceExitCode == 0
   }
+
   public void testListMissingCluster() throws Throwable {
     describe("exec the list command against an unknown cluster")
 
@@ -263,4 +357,14 @@ class TestActionList extends AgentMiniClusterTestBase {
     }
   }
 
+  static class TestSliderClient extends SliderClient {
+    public TestSliderClient() {
+      super()
+    }
+
+    @Override
+    protected void initHadoopBinding() throws IOException, SliderException {
+      sliderFileSystem = testFileSystem
+    }
+  }
 }

Reply via email to