diff --git a/.gitignore b/.gitignore
index a1c2a238a965f004ff76978ac1086aa6fe95caea..36f2b0786fad2032f47b2ece3ec41a932b94258d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,23 +1,105 @@
-# Compiled class file
-*.class
+# Byte-compiled / optimized / DLL files
+__pycache__
+*.py[cod]
+*$py.class
-# Log file
-*.log
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs*/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+node_modules
-# BlueJ files
-*.ctxt
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
+# Unit test / coverage reports
+htmlcov/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
-# Package Files #
-*.jar
-*.war
-*.nar
-*.ear
-*.zip
+# Environments
+env
+env3
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+.python-version
+.DS_Store
+.idea
+.mvn/
+mvnw
+mvnw.cmd
+*.iml
+*.gradle
+*.tgz
*.tar.gz
-*.rar
+*.jar
+target
+dev-support/mini-submarine/database
+dev-support/pysubmarine/sdk
+submarine-workbench/workbench-web/node
+submarine-workbench/workbench-web/node_modules
+submarine-workbench/workbench-web/dist
+submarine-workbench/workbench-web/package-lock.json
+submarine-workbench/workbench-web/npm-debug.log*
+submarine-test/e2e/Driver
+
+# interpreter temp files
+derby.log
+submarine-workbench/interpreter/spark-interpreter/metastore_db/
+spark-1.*-bin-hadoop*
+.spark-dist
+
+# submarine-cloud
+submarine-cloud/vendor/*
+submarine-cloud/output/*
+submarine-cloud/hack/conf/*
+submarine-cloud/hack/output/*
+submarine-cloud/bin/*
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
+submarine-security/spark-security/dependency-reduced-pom.xml
+submarine-security/spark-security/derby.log
+
+# submarine-cloud-v2
+submarine-cloud-v2/vendor/*
+submarine-cloud-v2/submarine-operator
+submarine-cloud-v2/helm-charts/submarine-operator/charts/*
+
+# vscode file
+.project
+.classpath
+.settings
+.factorypath
+.vscode/settings.json
+.vscode/tasks.json
+
+# jupyter notebook checkpoints
+.ipynb_checkpoints
+
+# redundant logging files
+*.log
diff --git a/LICENSE b/LICENSE
index 261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64..400e5543d43de4eb5ac5ba3c3bb9b986ed040a95 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,4 @@
+
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -199,3 +200,8 @@
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.
+
+--------------------------------------------------------------------------------
+This product bundles various third-party source code under other open source
+licenses. This section summarizes those components and their licenses.
+See licenses/ for text of these licenses.
\ No newline at end of file
diff --git a/LICENSE-binary b/LICENSE-binary
new file mode 100644
index 0000000000000000000000000000000000000000..38dae8af299fb62a1a1442addab5dd25a3dbfb97
--- /dev/null
+++ b/LICENSE-binary
@@ -0,0 +1,358 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+--------------------------------------------------------------------------------
+This project bundles some components that are also licensed under the Apache
+License Version 2.0:
+cglib:cglib:2.2.2
+com.fasterxml.jackson.core:jackson-annotations:2.7.8
+com.fasterxml.jackson.core:jackson-databind:2.7.8
+com.fasterxml.jackson.core:jackson-core:2.7.8
+com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.8.10
+com.fasterxml.woodstox:woodstox-core:5.0.3
+com.github.stephenc.jcip:jcip-annotations:1.0-1
+com.google.code.findbugs:jsr305:3.0.0
+com.google.code.findbugs:jsr305:1.3.9
+com.google.code.gson:gson:2.8.1
+com.google.code.gson:gson:2.2.4
+com.google.guava:guava:11.0.2
+com.google.inject:guice:3
+com.google.inject.extensions:guice-servlet:3
+com.jamesmurty.utils:java-xmlbuilder:0.4
+com.nimbusds:nimbus-jose-jwt:4.41.1
+com.squareup.okhttp:okhttp:2.7.5
+com.squareup.okio:okio:1.6.0
+commons-beanutils:commons-beanutils:1.7.0
+commons-beanutils:commons-beanutils-core:1.8.0
+commons-cli:commons-cli:1.2
+commons-codec:commons-codec:1.4
+commons-collections:commons-collections:3.2.2
+commons-configuration:commons-configuration:1.6
+commons-configuration:commons-configuration:1.1
+commons-daemon:commons-daemon:1.0.13
+commons-digester:commons-digester:1.8
+commons-io:commons-io:2.4
+commons-lang:commons-lang:2.6
+commons-logging:commons-logging:1.1.3
+commons-logging:commons-logging:1.1.1
+commons-net:commons-net:3.1
+io.netty:netty:3.7.0.Final
+io.netty:netty-all:4.0.23.Final
+javax.inject:javax.inject:1
+javax.validation:validation-api:1.1.0.Final
+log4j:log4j:1.2.17
+net.java.dev.jets3t:jets3t:0.9.0
+net.lingala.zip4j:zip4j:1.3.2
+net.minidev:accessors-smart:1.2
+net.minidev:json-smart:2.3
+org.apache.avro:avro:1.7.7
+org.apache.avro:avro:1.8.2
+org.apache.commons:commons-lang3:3.4
+org.apache.commons:commons-lang3:3.7
+org.apache.commons:commons-text:1.4
+org.apache.commons:commons-compress:1.4.1
+org.apache.commons:commons-math3:3.1.1
+org.apache.curator:curator-client:2.7.1
+org.apache.curator:curator-framework:2.7.1
+org.apache.curator:curator-recipes:2.7.1
+org.apache.directory.api:api-asn1-api:1.0.0-M20
+org.apache.directory.api:api-util:1.0.0-M20
+org.apache.directory.server:apacheds-i18n:2.0.0-M15
+org.apache.directory.server:apacheds-kerberos-codec:2.0.0-M15
+org.apache.hadoop:hadoop-yarn-api:2.9.2
+org.apache.hadoop:hadoop-yarn-client:2.9.2
+org.apache.hadoop:hadoop-yarn-common:2.9.2
+org.apache.hadoop:hadoop-common:2.9.2
+org.apache.hadoop:hadoop-annotations:2.9.2
+org.apache.hadoop:hadoop-auth:2.9.2
+org.apache.hadoop:hadoop-hdfs:2.9.2
+org.apache.hadoop:hadoop-hdfs-client:2.9.2
+org.apache.htrace:htrace-core4:4.1.0-incubating
+org.apache.httpcomponents:httpclient:4.5.2
+org.apache.httpcomponents:httpcore:4.4.4
+org.apache.submarine:submarine-core:0.5.0
+org.apache.zookeeper:zookeeper:3.4.6
+org.codehaus.jackson:jackson-core-asl:1.9.13
+org.codehaus.jackson:jackson-mapper-asl:1.9.13
+org.codehaus.jackson:jackson-jaxrs:1.9.13
+org.codehaus.jackson:jackson-xc:1.9.13
+org.codehaus.jettison:jettison:1.1
+org.eclipse.jetty:jetty-jmx:9.4.18.v20190429
+org.eclipse.jetty:jetty-webapp:9.4.18.v20190429
+org.eclipse.jetty:jetty-client:9.4.18.v20190429
+org.eclipse.jetty:jetty-http:9.4.18.v20190429
+org.eclipse.jetty:jetty-io:9.4.18.v20190429
+org.eclipse.jetty:jetty-security:9.4.18.v20190429
+org.eclipse.jetty:jetty-server:9.4.18.v20190429
+org.eclipse.jetty:jetty-servlet:9.4.18.v20190429
+org.eclipse.jetty:jetty-util:9.4.18.v20190429
+org.eclipse.jetty:jetty-xml:9.4.18.v20190429
+org.eclipse.jetty.websocket:websocket-server:9.4.18.v20190429
+org.eclipse.jetty.websocket:websocket-api:9.4.18.v20190429
+org.eclipse.jetty.websocket:websocket-client:9.4.18.v20190429
+org.eclipse.jetty.websocket:websocket-common:9.4.18.v20190429
+org.eclipse.jetty.websocket:websocket-servlet:9.4.18.v20190429
+org.mortbay.jetty:jetty-sslengine:6.1.26
+org.mortbay.jetty:jetty-util:6.1.26
+org.mortbay.jetty:jetty:6.1.26
+org.mybatis:mybatis:3.2.8
+org.xerial.snappy:snappy-java:1.0.5
+org.xerial.snappy:snappy-java:1.1.1.3
+org.yaml:snakeyaml:1.16
+xerces:xercesImpl:2.9.1
+xml-apis:xml-apis:1.3.04
+
+
+--------------------------------------------------------------------------------
+This product bundles various third-party binaries under other open source
+licenses. This section summarizes those components and their licenses.
+See licenses-binary/ for text of these licenses.
+
+MIT License
+-----------
+org.slf4j:slf4j-api:1.7.25
+com.github.pagehelper:Mybatis-PageHelper:5.1.10
+
+
+Eclipse Distribution License - v 1.0
+-----------
+org.eclipse.jgit
+
+
+Public Domain
+-------------
+aopalliance:aopalliance:1.0
+
+
+BSD 2-Clause
+------------
+com.linkedin.tony:tony-core:0.3.21
+
+
+BSD 3-Clause
+------------
+org.hamcrest:hamcrest-core:1.3
+com.google.protobuf:protobuf-java:2.5.0
+com.thoughtworks.paranamer:paranamer:2.3
+org.ow2.asm:asm:5.0.4
+asm:asm:3.3.1
+
+
+CDDL 1.1 + GPLv2 with classpath exception
+------------
+org.glassfish.jersey.core:jersey-common:2.27
+org.glassfish.jersey.media:jersey-media-json-jackson:2.27
+org.glassfish.jersey.containers:jersey-container-servlet-core
+org.glassfish.jersey.inject:jersey-hk2:2.27
+org.glassfish.jersey.ext:jersey-entity-filtering:2.27
+com.sun.jersey:jersey-client:1.9
+com.sun.jersey.contribs:jersey-guice:1.9
+com.sun.xml.bind:jaxb-impl:2.2.3-1
+javax.xml.bind:jaxb-api:2.2.11
+javax.ws.rs:javax.ws.rs-api:2.1
+javax.annotation:javax.annotation-api:1.2
+javax.servlet:javax.servlet-api:3.1.0
+org.glassfish.hk2:hk2-api:2.5.0-b42
+org.glassfish.hk2.external:aopalliance-repackaged:2.5.0-b42
+javax.servlet.jsp:jsp-api:2.1
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000000000000000000000000000000000000..4ec5251bf2f1acfd85ac8cc266a67fe2f1177ce7
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,27 @@
+Apache Submarine
+Copyright 2019 and onwards The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Export Control Notice
+---------------------
+
+This distribution includes cryptographic software. The country in
+which you currently reside may have restrictions on the import,
+possession, use, and/or re-export to another country, of
+encryption software. BEFORE using any encryption software, please
+check your country's laws, regulations and policies concerning the
+import, possession, or use, and re-export of encryption software, to
+see if this is permitted. See for more
+information.
+
+The U.S. Government Department of Commerce, Bureau of Industry and
+Security (BIS), has classified this software as Export Commodity
+Control Number (ECCN) 5D002.C.1, which includes information security
+software using or performing cryptographic functions with asymmetric
+algorithms. The form and manner of this Apache Software Foundation
+distribution makes it eligible for export under the License Exception
+ENC Technology Software Unrestricted (TSU) exception (see the BIS
+Export Administration Regulations, Section 740.13) for both object
+code and source code.
\ No newline at end of file
diff --git a/NOTICE-binary b/NOTICE-binary
new file mode 100644
index 0000000000000000000000000000000000000000..8b0120677dfde41c0cdbfbabb843be354c88eb0d
--- /dev/null
+++ b/NOTICE-binary
@@ -0,0 +1,66 @@
+Apache Submarine
+Copyright 2019 and onwards The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Export Control Notice
+---------------------
+
+This distribution includes cryptographic software. The country in
+which you currently reside may have restrictions on the import,
+possession, use, and/or re-export to another country, of
+encryption software. BEFORE using any encryption software, please
+check your country's laws, regulations and policies concerning the
+import, possession, or use, and re-export of encryption software, to
+see if this is permitted. See for more
+information.
+
+The U.S. Government Department of Commerce, Bureau of Industry and
+Security (BIS), has classified this software as Export Commodity
+Control Number (ECCN) 5D002.C.1, which includes information security
+software using or performing cryptographic functions with asymmetric
+algorithms. The form and manner of this Apache Software Foundation
+distribution makes it eligible for export under the License Exception
+ENC Technology Software Unrestricted (TSU) exception (see the BIS
+Export Administration Regulations, Section 740.13) for both object
+code and source code.
+
+
+--------------------------------------------------------------------------------
+This product bundles a same/modified portion of third-party binaries
+and optionally depends on them (NO NEED FOR PERMISSIVELY-LICENSED DEPENDENCIES,
+aka, Category A,
+per http://www.apache.org/dev/licensing-howto.html#permissive-deps). The license
+text can be found in licenses-binary folder.
+
+TonY
+-------------
+Copyright 2018 LinkedIn Corporation
+All Rights Reserved.
+
+Licensed under the BSD 2-Clause License (the "License").
+See LICENSE in the project root for license information.
+
+================================================================================
+
+This product includes/uses TensorFlow (https://github.com/tensorflow)
+Copyright 2018 The TensorFlow Authors
+License: Apache-2.0
+
+This product includes/uses TensorFlowOnYARN (https://github.com/Intel-bigdata/TensorFlowOnYARN)
+Copyright 2018 Intel-bigdata
+License: Apache-2.0
+
+================================================================================
+
+In addition, this product automatically loads third party code from an external repository
+using the Gradle build system. Such third party code is subject to other license
+terms than as set forth above. In addition, such third party code may also
+depend on and load multiple tiers of dependencies.
+
+
+jgit
+-------------
+Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
+Licenced under Eclipse Distribution License - v 1.0
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2980443ee5ab5876ae0805b4ba87c3bdde9dab87
--- /dev/null
+++ b/README.md
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+[](https://travis-ci.org/apache/submarine) [](https://www.apache.org/licenses/LICENSE-2.0.html) [](http://hits.dwyl.io/apache/submarine) [](https://badge.fury.io/py/apache-submarine)
+
+# What is Apache Submarine?
+
+**Apache Submarine** (Submarine for short) is an **End-to-End Machine Learning PLATFORM** to allow data scientists to create end-to-end machine learning workflows. To elaborate, on **Submarine**, data scientists can finish each stage in the ML model lifecycle, including data exploration, data pipeline creation, model training, serving, and monitoring.
+
+## Why Submarine?
+
+Some open-source and commercial projects are trying to build an end-to-end ML platform. What's the vision of Submarine?
+
+### Problems
+
+1) Many platforms lack easy-to-use user interfaces (API, SDK, and IDE, etc.)
+2) In the same company, data scientists in different teams usually spend much time on developments of existing feature sets and models.
+3) Data scientists put emphasis on domain-specific tasks (e.g. Click-Through-Rate), but they need to implement their models from scratch with SDKs provided by existing platforms.
+4) Many platforms lack a unified workbench to manage each component in the ML lifecycle.
+
+_Theodore Levitt_ once said:
+
+```
+“People don’t want to buy a quarter-inch drill. They want a quarter-inch hole.”
+```
+
+### Goals of Submarine
+
+#### Model Training (Experiment)
+- Run/Track distributed training `experiment` on prem or cloud via easy-to-use UI/API/SDK.
+- Easy for data scientists to manage versions of `experiment` and dependencies of `environment`
+- Support popular machine learning frameworks, including **TensorFlow**, **PyTorch**, **Horovod**, and **MXNet**
+- Provide pre-defined **template** for data scientists to implement domain-specific tasks easily (e.g. using DeepFM template to build a CTR prediction model)
+- Support many compute resources (e.g. CPU and GPU, etc.)
+- Support **Kubernetes** and **YARN**
+- Pipeline is also on the backlog, we will look into pipeline for training in the future.
+
+#### Notebook Service
+
+- Submarine aims to provide a notebook service (e.g. Jupyter notebook) which allows users to manage notebook instances running on the cluster.
+
+#### Model Management (Serving/versioning/monitoring, etc.)
+
+- Model management for model-serving/versioning/monitoring is on the roadmap.
+
+## Easy-to-use User Interface
+
+As mentioned above, Submarine attempts to provide **Data-Scientist-friendly** UI to make data scientists have a good user experience. Here're some examples.
+
+### Example: Submit a distributed Tensorflow experiment via Submarine Python SDK
+
+#### Run a Tensorflow Mnist experiment
+```python
+
+# New a submarine client of the submarine server
+submarine_client = submarine.ExperimentClient(host='http://localhost:8080')
+
+# The experiment's environment, could be Docker image or Conda environment based
+environment = EnvironmentSpec(image='apache/submarine:tf-dist-mnist-test-1.0')
+
+# Specify the experiment's name, framework it's using, namespace it will run in,
+# the entry point. It can also accept environment variables. etc.
+# For PyTorch job, the framework should be 'Pytorch'.
+experiment_meta = ExperimentMeta(name='mnist-dist',
+ namespace='default',
+ framework='Tensorflow',
+ cmd='python /var/tf_dist_mnist/dist_mnist.py --train_steps=100')
+# 1 PS task of 2 cpu, 1GB
+ps_spec = ExperimentTaskSpec(resources='cpu=2,memory=1024M',
+ replicas=1)
+# 1 Worker task
+worker_spec = ExperimentTaskSpec(resources='cpu=2,memory=1024M',
+ replicas=1)
+
+# Wrap up the meta, environment and task specs into an experiment.
+# For PyTorch job, the specs would be "Master" and "Worker".
+experiment_spec = ExperimentSpec(meta=experiment_meta,
+ environment=environment,
+ spec={'Ps':ps_spec, 'Worker': worker_spec})
+
+# Submit the experiment to submarine server
+experiment = submarine_client.create_experiment(experiment_spec=experiment_spec)
+
+# Get the experiment ID
+id = experiment['experimentId']
+
+```
+
+#### Query a specific experiment
+```python
+submarine_client.get_experiment(id)
+```
+
+#### Wait for finish
+
+```python
+submarine_client.wait_for_finish(id)
+```
+
+#### Get the experiment's log
+```python
+submarine_client.get_log(id)
+```
+
+#### Get all running experiment
+```python
+submarine_client.list_experiments(status='running')
+```
+
+For a quick-start, see [Submarine On K8s](docs/userdocs/k8s/README.md)
+
+
+### Example: Submit a pre-defined experiment template job
+
+### Example: Submit an experiment via Submarine UI
+
+(Available on 0.6.0, see Roadmap)
+
+## Architecture, Design and requirements
+
+If you want to know more about Submarine's architecture, components, requirements and design doc, they can be found on [Architecture-and-requirement](docs/design/architecture-and-requirements.md)
+
+Detailed design documentation, implementation notes can be found at: [Implementation notes](docs/design/implementation-notes.md)
+
+## Apache Submarine Community
+
+Read the [Apache Submarine Community Guide](./docs/community/README.md)
+
+How to contribute [Contributing Guide](./docs/community/contributing.md)
+
+Issue Tracking: https://issues.apache.org/jira/projects/SUBMARINE
+
+## User Document
+
+See [User Guide Home Page](docs/user-guide-home.md)
+
+## Developer Document
+
+See [Developer Guide Home Page](docs/development-guide-home.md)
+
+## Roadmap
+
+What to know more about what's coming for Submarine? Please check the roadmap out: https://cwiki.apache.org/confluence/display/SUBMARINE/Roadmap
+
+## License
+
+The Apache Submarine project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.
diff --git a/bin/common.sh b/bin/common.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ecf946995d8a400adeb4abf29bf968c44f00c14d
--- /dev/null
+++ b/bin/common.sh
@@ -0,0 +1,100 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+
+export DEFAULT_MYSQL_VERSION=5.1.39
+
+if [[ -L ${BASH_SOURCE-$0} ]]; then
+ FWDIR=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ FWDIR=$(dirname "${BASH_SOURCE-$0}")
+fi
+
+if [[ -z "${SUBMARINE_HOME}" ]]; then
+ # Make SUBMARINE_HOME look cleaner in logs by getting rid of the
+ # extra ../
+ export SUBMARINE_HOME="$(cd "${FWDIR}/.."; pwd)"
+fi
+
+if [[ -z "${SUBMARINE_CONF_DIR}" ]]; then
+ export SUBMARINE_CONF_DIR="${SUBMARINE_HOME}/conf"
+fi
+
+if [[ -z "${SUBMARINE_LOG_DIR}" ]]; then
+ export SUBMARINE_LOG_DIR="${SUBMARINE_HOME}/logs"
+fi
+
+if [[ -f "${SUBMARINE_CONF_DIR}/submarine-env.sh" ]]; then
+ . "${SUBMARINE_CONF_DIR}/submarine-env.sh"
+fi
+
+SUBMARINE_SERVER_CLASSPATH+=":${SUBMARINE_CONF_DIR}"
+
+function add_each_jar_in_dir(){
+ if [[ -d "${1}" ]]; then
+ for jar in $(find -L "${1}" -maxdepth 1 -name '*jar'); do
+ SUBMARINE_SERVER_CLASSPATH="$jar:$SUBMARINE_SERVER_CLASSPATH"
+ done
+ fi
+}
+
+function add_each_jar_in_dir_recursive(){
+ if [[ -d "${1}" ]]; then
+ for jar in $(find -L "${1}" -type f -name '*jar'); do
+ SUBMARINE_SERVER_CLASSPATH="$jar:$SUBMARINE_SERVER_CLASSPATH"
+ done
+ fi
+}
+
+function add_jar_in_dir(){
+ if [[ -d "${1}" ]]; then
+ SUBMARINE_SERVER_CLASSPATH="${1}/*:${SUBMARINE_SERVER_CLASSPATH}"
+ fi
+}
+
+function download_mysql_jdbc_jar(){
+ if [[ -z "${MYSQL_JAR_URL}" ]]; then
+ if [[ -z "${MYSQL_VERSION}" ]]; then
+ MYSQL_VERSION="${DEFAULT_MYSQL_VERSION}"
+ fi
+ MYSQL_JAR_URL="https://repo1.maven.org/maven2/mysql/mysql-connector-java/${MYSQL_VERSION}/mysql-connector-java-${MYSQL_VERSION}.jar"
+ fi
+
+ echo "Downloading mysql jdbc jar from ${MYSQL_JAR_URL}."
+ if type wget >/dev/null 2>&1; then
+ wget ${MYSQL_JAR_URL} -P "${SUBMARINE_HOME}/lib" --no-check-certificate
+ elif type curl >/dev/null 2>&1; then
+ curl -o "${SUBMARINE_HOME}/lib/mysql-connector-java-${MYSQL_VERSION}.jar" ${MYSQL_JAR_URL}
+ else
+ echo 'We need a tool to transfer data from or to a server. Such as wget/curl.'
+ echo 'Bye, bye!'
+ exit 1
+ fi
+
+ echo "Mysql jdbc jar is downloaded and put in the path of submarine/lib."
+}
+
+JAVA_OPTS+=" -Dfile.encoding=UTF-8"
+JAVA_OPTS+=" -Dlog4j.configuration=file://${SUBMARINE_CONF_DIR}/log4j.properties"
+export JAVA_OPTS
+
+if [[ -n "${JAVA_HOME}" ]]; then
+ JAVA_RUNNER="${JAVA_HOME}/bin/java"
+else
+ JAVA_RUNNER=java
+fi
+export JAVA_RUNNER
diff --git a/bin/submarine-daemon.sh b/bin/submarine-daemon.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f7fcdc8d365a5cf9946827c8e7601abd4ae5cb44
--- /dev/null
+++ b/bin/submarine-daemon.sh
@@ -0,0 +1,185 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# description: Start and stop daemon script for.
+#
+
+USAGE="-e Usage: submarine-daemon.sh {start|stop|restart|status}"
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ BIN=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ BIN=$(dirname ${BASH_SOURCE-$0})
+fi
+export BIN=$(cd "${BIN}">/dev/null; pwd)
+GET_MYSQL_JAR=false
+
+. "${BIN}/common.sh"
+
+cd ${BIN}/>/dev/null
+
+SUBMARINE_SERVER_NAME="Submarine Server"
+SUBMARINE_SERVER_LOGFILE="${SUBMARINE_LOG_DIR}/submarine.log"
+SUBMARINE_SERVER_MAIN=org.apache.submarine.server.SubmarineServer
+JAVA_OPTS+="${SUBMARINE_SERVER_JAVA_OPTS} ${SUBMARINE_SERVER_MEM} -Dsubmarine.log.file=${SUBMARINE_SERVER_LOGFILE}"
+
+add_jar_in_dir "${BIN}/../lib"
+
+function initialize_default_directories() {
+ if [[ ! -d "${SUBMARINE_LOG_DIR}" ]]; then
+ echo "Log dir doesn't exist, create ${SUBMARINE_LOG_DIR}"
+ $(mkdir -p "${SUBMARINE_LOG_DIR}")
+ fi
+}
+
+function found_submarine_server_pid() {
+ process='SubmarineServer';
+ RUNNING_PIDS=$(ps x | grep ${process} | grep -v grep | awk '{print $1}');
+
+ if [[ -z "${RUNNING_PIDS}" ]]; then
+ return
+ fi
+
+ if ! kill -0 ${RUNNING_PIDS} > /dev/null 2>&1; then
+ echo "${SUBMARINE_SERVER_NAME} running but process is dead"
+ fi
+
+ echo "${RUNNING_PIDS}"
+}
+
+function wait_for_submarine_server_to_die() {
+ local pid
+ local count
+
+ pid=`found_submarine_server_pid`
+ timeout=10
+ count=0
+ timeoutTime=$(date "+%s")
+ let "timeoutTime+=$timeout"
+ currentTime=$(date "+%s")
+ forceKill=1
+
+ while [[ $currentTime -lt $timeoutTime ]]; do
+ $(kill ${pid} > /dev/null 2> /dev/null)
+ if kill -0 ${pid} > /dev/null 2>&1; then
+ sleep 3
+ else
+ forceKill=0
+ break
+ fi
+ currentTime=$(date "+%s")
+ done
+
+ if [[ forceKill -ne 0 ]]; then
+ $(kill -9 ${pid} > /dev/null 2> /dev/null)
+ fi
+}
+
+function check_jdbc_jar() {
+ if [[ -d "${1}" ]]; then
+ mysql_connector_exists=$(find -L "${1}" -name "mysql-connector*")
+ if [[ -z "${mysql_connector_exists}" ]]; then
+ if [[ ${GET_MYSQL_JAR} = true ]]; then
+ download_mysql_jdbc_jar
+ else
+ echo -e "\\033[31mError: There is no mysql jdbc jar in lib.\\033[0m"
+ echo -e "\\033[31mPlease download a mysql jdbc jar and put it under lib manually.\\033[0m"
+ echo -e "\\033[31mOr add a parameter getMysqlJar, like this:\n./bin/submarine-daemon.sh start getMysqlJar\\033[0m"
+ echo -e "\\033[31mIt would download mysql jdbc jar automatically.\\033[0m"
+ exit 1
+ fi
+ fi
+ fi
+}
+
+function start() {
+ local pid
+
+ pid=`found_submarine_server_pid`
+ if [[ ! -z "$pid" && "$pid" != 0 ]]; then
+ echo "${SUBMARINE_SERVER_NAME}:${pid} is already running"
+ return 1;
+ fi
+
+ check_jdbc_jar "${BIN}/../lib"
+
+ initialize_default_directories
+
+ echo "SUBMARINE_SERVER_CLASSPATH: ${SUBMARINE_SERVER_CLASSPATH}" >> "${SUBMARINE_SERVER_LOGFILE}"
+
+ nohup $JAVA_RUNNER $JAVA_OPTS -cp $SUBMARINE_SERVER_CLASSPATH $SUBMARINE_SERVER_MAIN >> "${SUBMARINE_SERVER_LOGFILE}" 2>&1 < /dev/null &
+ pid=$!
+ if [[ ! -z "${pid}" ]]; then
+ echo "${SUBMARINE_SERVER_NAME} start"
+ return 0;
+ fi
+}
+
+function stop() {
+ local pid
+ pid=`found_submarine_server_pid`
+
+ if [[ -z "$pid" ]]; then
+ echo "${SUBMARINE_SERVER_NAME} is not running"
+ return 0;
+ else
+ # submarine workbench daemon kill
+ wait_for_submarine_server_to_die
+ echo "${SUBMARINE_SERVER_NAME} stop"
+ fi
+}
+
+function find_submarine_server_process() {
+ local pid
+ pid=`found_submarine_server_pid`
+
+ if [[ -z "$pid" ]]; then
+ echo "${SUBMARINE_SERVER_NAME} is not running"
+ return 1
+ else
+ if ! kill -0 ${pid} > /dev/null 2>&1; then
+ echo "${SUBMARINE_SERVER_NAME} running but process is dead"
+ return 1
+ else
+ echo "${SUBMARINE_SERVER_NAME} is running"
+ fi
+ fi
+}
+
+if [[ "$2" = "getMysqlJar" ]]; then
+ export GET_MYSQL_JAR=true
+fi
+
+case "${1}" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ echo "${SUBMARINE_SERVER_NAME} is restarting" >> "${SUBMARINE_SERVER_LOGFILE}"
+ stop
+ start
+ ;;
+ status)
+ find_submarine_server_process
+ ;;
+ *)
+ echo ${USAGE}
+esac
diff --git a/bin/submarine.sh b/bin/submarine.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8a5d6e8d72157e00bc3ef0ec56065ef3621e2d51
--- /dev/null
+++ b/bin/submarine.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+#
+# 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.
+
+USAGE="Usage: bin/submarine.sh [--config ]"
+
+if [[ "$1" == "--config" ]]; then
+ shift
+ conf_dir="$1"
+ if [[ ! -d "${conf_dir}" ]]; then
+ echo "ERROR : ${conf_dir} is not a directory"
+ echo ${USAGE}
+ exit 1
+ else
+ export SUBMARINE_CONF_DIR="${conf_dir}"
+ fi
+ shift
+fi
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ BIN=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ BIN=$(dirname ${BASH_SOURCE-$0})
+fi
+export BIN=$(cd "${BIN}">/dev/null; pwd)
+GET_MYSQL_JAR=false
+
+. "${BIN}/common.sh"
+
+cd ${BIN}/>/dev/null
+
+SUBMARINE_SERVER_NAME="Submarine Server"
+SUBMARINE_SERVER_LOGFILE="${SUBMARINE_LOG_DIR}/submarine.log"
+SUBMARINE_SERVER_MAIN=org.apache.submarine.server.SubmarineServer
+JAVA_OPTS+="${SUBMARINE_SERVER_JAVA_OPTS:-""} ${SUBMARINE_SERVER_MEM:-""} -Dsubmarine.log.file=${SUBMARINE_SERVER_LOGFILE}"
+
+add_jar_in_dir "${BIN}/../lib"
+
+if [[ ! -d "${SUBMARINE_LOG_DIR}" ]]; then
+ echo "Log dir doesn't exist, create ${SUBMARINE_LOG_DIR}"
+ $(mkdir -p "${SUBMARINE_LOG_DIR}")
+fi
+
+exec $JAVA_RUNNER $JAVA_OPTS -cp ${SUBMARINE_SERVER_CLASSPATH} ${SUBMARINE_SERVER_MAIN} "$@" >> "${SUBMARINE_SERVER_LOGFILE}" 2>&1
diff --git a/conf/log4j.properties b/conf/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2f44c7217d92b7d27c10e54c45cce707a572fb92
--- /dev/null
+++ b/conf/log4j.properties
@@ -0,0 +1,59 @@
+# 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.
+
+# Define some default values that can be overridden by system properties
+submarine.log.threshold=ALL
+submarine.root.logger=INFO, DRFA, console
+submarine.log.dir=/tmp
+submarine.log.file=submarine.log
+
+log4j.rootLogger=${submarine.root.logger}, EventCounter
+
+# Logging Threshold
+log4j.threshold=${submarine.log.threshold}
+
+#
+# Daily Rolling File Appender
+#
+# Use the PidDailyerRollingFileAppend class instead if you want to use separate log files
+# for different CLI session.
+
+log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
+
+log4j.appender.DRFA.File=${submarine.log.dir}/${submarine.log.file}
+
+# Rollover at midnight
+log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
+
+# 30-day backup
+#log4j.appender.DRFA.MaxBackupIndex=30
+log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
+
+# Pattern format: Date LogLevel LoggerName LogMessage
+#log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
+# Debugging Pattern format
+log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t]: %c{2} (%F:%M(%L)) - %m%n
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} [%t]: %p %c{2}: %m%n
+log4j.appender.console.encoding=UTF-8
diff --git a/conf/log4j.properties.template b/conf/log4j.properties.template
new file mode 100755
index 0000000000000000000000000000000000000000..579a382764c700e706f0e56ea0c1e1083bad77ce
--- /dev/null
+++ b/conf/log4j.properties.template
@@ -0,0 +1,59 @@
+# 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.
+
+# Define some default values that can be overridden by system properties
+submarine.log.threshold=ALL
+submarine.root.logger=INFO,DRFA,console
+submarine.log.dir=/tmp
+submarine.log.file=submarine.log
+
+log4j.rootLogger=${submarine.root.logger}, EventCounter
+
+# Logging Threshold
+log4j.threshold=${submarine.log.threshold}
+
+#
+# Daily Rolling File Appender
+#
+# Use the PidDailyerRollingFileAppend class instead if you want to use separate log files
+# for different CLI session.
+
+log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
+
+log4j.appender.DRFA.File=${submarine.log.dir}/${submarine.log.file}
+
+# Rollover at midnight
+log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
+
+# 30-day backup
+#log4j.appender.DRFA.MaxBackupIndex=30
+log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
+
+# Pattern format: Date LogLevel LoggerName LogMessage
+#log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
+# Debugging Pattern format
+log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t]: %c{2} (%F:%M(%L)) - %m%n
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} [%t]: %p %c{2}: %m%n
+log4j.appender.console.encoding=UTF-8
diff --git a/conf/submarine-env.sh.template b/conf/submarine-env.sh.template
new file mode 100644
index 0000000000000000000000000000000000000000..97ae1d860b01b4f943582ec3b5b5a8094acb43a7
--- /dev/null
+++ b/conf/submarine-env.sh.template
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+
+# export JAVA_HOME=java
+
+# Debug Submarine server
+# export SUBMARINE_SERVER_JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
+
+# Set Submarine server memory
+# export SUBMARINE_SERVER_MEM="-Xms1024m -Xmx1024m -XX:MaxPermSize=512m"
+
+# Set Submarine server classpath. If you want to visit hdfs, just add hadoop
+# configuration path.
+# export SUBMARINE_SERVER_CLASSPATH+=":/usr/local/hadoop/etc/hadoop"
diff --git a/conf/submarine-site.xml b/conf/submarine-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..eba252937c94678050fe322a719cd81f1ae154d1
--- /dev/null
+++ b/conf/submarine-site.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+ submarine.cluster.addr
+
+ submarine cluster address list, e.g. ip1:port1;ip2:port2;ip3:port3
+
+
+
+ submarine.server.addr
+ 0.0.0.0
+ Server address
+
+
+
+ submarine.server.port
+ 8080
+ Server port.
+
+
+
+ submarine.server.ssl
+ false
+ Should SSL be used by the submarine server?
+
+
+
+ submarine.server.ssl.port
+ 8443
+ Server ssl port. (used when ssl property is set to true)
+
+
+
+ submarine.server.ssl.client.auth
+ false
+ Should client authentication be used for SSL connections?
+
+
+
+ submarine.server.ssl.keystore.path
+ keystore
+ Path to keystore relative to submarine configuration directory
+
+
+
+ submarine.server.ssl.keystore.type
+ JKS
+ The format of the given keystore (e.g. JKS or PKCS12)
+
+
+
+ submarine.server.ssl.keystore.password
+ change me
+ Keystore password. Can be obfuscated by the Jetty Password tool
+
+
+
+
+
+ submarine.server.ssl.truststore.path
+ truststore
+ Path to truststore relative to submarine configuration directory. Defaults to the keystore path
+
+
+
+ submarine.server.ssl.truststore.type
+ JKS
+ The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type
+
+
+
+
+
+ workbench.web.war
+ ../submarine-workbench-web.war
+ Submarine workbench web war file path.
+
+
+
+ jdbc.driverClassName
+ com.mysql.jdbc.Driver
+
+
+ jdbc.url
+ jdbc:mysql://127.0.0.1:3306/submarine?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false
+
+
+ jdbc.username
+ submarine
+
+
+ jdbc.password
+ password
+
+
+
+ metastore.jdbc.url
+ jdbc:mysql://127.0.0.1:3306/metastore?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false
+
+
+ metastore.jdbc.username
+ metastore
+
+
+ metastore.jdbc.password
+ password
+
+
+
+ submarine.runtime.class
+ org.apache.submarine.server.submitter.yarn.YarnRuntimeFactory
+ RuntimeFactory for Submarine jobs
+
+
+
+ submarine.server.rpc.enabled
+ false
+ Run jobs using rpc server.
+
+
+
+ submarine.server.rpc.port
+ 8980
+ Rpc server port
+
+
+
+ submarine.submitter
+ k8s
+ The submitter which you want used in the server. Build-in k8s
+
+
+
diff --git a/conf/submarine-site.xml.template b/conf/submarine-site.xml.template
new file mode 100755
index 0000000000000000000000000000000000000000..ccb2aa0ea398786a7af19fcf25d009d69c417648
--- /dev/null
+++ b/conf/submarine-site.xml.template
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+ submarine.cluster.addr
+
+ submarine cluster address list, e.g. ip1:port1;ip2:port2;ip3:port3
+
+
+
+ submarine.server.addr
+ 0.0.0.0
+ Server address
+
+
+
+ submarine.server.port
+ 8080
+ Server port.
+
+
+
+ submarine.server.ssl
+ false
+ Should SSL be used by the submarine server?
+
+
+
+ submarine.server.ssl.port
+ 8443
+ Server ssl port. (used when ssl property is set to true)
+
+
+
+ submarine.server.ssl.client.auth
+ false
+ Should client authentication be used for SSL connections?
+
+
+
+ submarine.server.ssl.keystore.path
+ keystore
+ Path to keystore relative to submarine configuration directory
+
+
+
+ submarine.server.ssl.keystore.type
+ JKS
+ The format of the given keystore (e.g. JKS or PKCS12)
+
+
+
+ submarine.server.ssl.keystore.password
+ change me
+ Keystore password. Can be obfuscated by the Jetty Password tool
+
+
+
+
+
+ submarine.server.ssl.truststore.path
+ truststore
+ Path to truststore relative to submarine configuration directory. Defaults to the keystore path
+
+
+
+ submarine.server.ssl.truststore.type
+ JKS
+ The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type
+
+
+
+
+
+ workbench.web.war
+ ../submarine-workbench-web.war
+ Submarine workbench web war file path.
+
+
+
+ jdbc.driverClassName
+ com.mysql.jdbc.Driver
+
+
+ jdbc.url
+ jdbc:mysql://127.0.0.1:3306/submarine?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false
+
+
+ jdbc.username
+ submarine
+
+
+ jdbc.password
+ password
+
+
+
+ metastore.jdbc.url
+ jdbc:mysql://127.0.0.1:3306/metastore?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false
+
+
+ metastore.jdbc.username
+ metastore
+
+
+ metastore.jdbc.password
+ password
+
+
+
+ submarine.runtime.class
+ org.apache.submarine.server.submitter.yarn.YarnRuntimeFactory
+ RuntimeFactory for Submarine jobs
+
+
+
+ submarine.server.rpc.enabled
+ false
+ Run jobs using rpc server.
+
+
+
+ submarine.server.rpc.port
+ 8980
+ Rpc server port
+
+
+
+ submarine.submitter
+ k8s
+ The submitter which you want used in the server. Build-in k8s
+
+
diff --git a/dev-support/cicd/Dockerfile b/dev-support/cicd/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..edf04025602354e65474de8031699ed60f10fb50
--- /dev/null
+++ b/dev-support/cicd/Dockerfile
@@ -0,0 +1,50 @@
+# 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.
+
+FROM ubuntu:18.04
+RUN \
+ apt-get update && \
+ apt-get install -y wget vim git python-pip zlib1g-dev libssl-dev && \
+ wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz && \
+ tar xzf Python-2.7.13.tgz && cd Python-2.7.13 && ./configure --with-zlib && make install && make altinstall && \
+ cd /root && wget https://files.pythonhosted.org/packages/59/38/55dd25a965990bd93f77eb765b189e72cf581ce1c2de651cb7b1dea74ed1/virtualenv-16.2.0.tar.gz && \
+ tar xf virtualenv-16.2.0.tar.gz && \
+ python virtualenv-16.2.0/virtualenv.py venv2.7 && \
+ . venv2.7/bin/activate && \
+ pip install jira && \
+ deactivate
+
+RUN \
+ git clone https://gitbox.apache.org/repos/asf/submarine.git && \
+ cd submarine && \
+ git remote rename origin apache && \
+ git remote add apache-github https://github.com/apache/submarine.git
+ADD \
+ entry.sh /entry.sh
+ENV \
+ SUBMARINE_HOME=/submarine \
+ PYTHON_VENV_PATH=/root
+
+RUN apt-get update && apt-get -y install bundler
+
+RUN \
+ cd / && \
+ git clone https://gitbox.apache.org/repos/asf/submarine-site.git && \
+ cd /submarine-site && bundle update
+
+ENV \
+ SUBMARINE_SITE=/submarine-site
+
+CMD /entry.sh
diff --git a/dev-support/cicd/HowToRelease.md b/dev-support/cicd/HowToRelease.md
new file mode 100644
index 0000000000000000000000000000000000000000..cd4d297493c9080181ea50d558e2bc721059112d
--- /dev/null
+++ b/dev-support/cicd/HowToRelease.md
@@ -0,0 +1,198 @@
+# How To Release Apache Submarine
+This document is for Apache Submarine Release Manager to do a new release.
+
+## 1. Preparation
+If you have not already done so, generate your PGP key and append your [signing key](http://www.apache.org/dev/release-signing.html#keys-policy) to the [KEYS](https://dist.apache.org/repos/dist/release/submarine/KEYS) file. Once you commit your changes (ask for PMC's help if you cannot), they will automatically be propagated to the website. Also upload your key to a public key server if you haven't.
+End users use the KEYS file to validate that releases were done by an Apache Committer.
+
+```
+# generate key and send keys to a keyserver
+gpg --gen-key
+gpg --list-sigs
+gpg --keyserver pgp.mit.edu --send-keys
+gpg --refresh-keys --keyserver pgp.mit.edu
+
+
+# ask for PMC’s help to sign the key and add your key to the submarine KEYS (Only PMCs has permission). The PMC should do
+gpg --keyserver pgp.mit.edu --recv-key
+gpg --sign-key
+svn co --depth immediates https://dist.apache.org/repos/dist apache-dist
+cd apache-dist
+svn update --set-depth immediates release/submarine
+cd release/submarine
+gpg --list-sigs >> KEYS
+gpg --armor --export >> KEYS
+svn ci -m "Add 's key"
+```
+
+## 2. Send Release Plan
+It's better to send a release plan email informing code freeze date and release date.
+
+## 3. Clean up the JIRA
+Bulk update JIRA to move out non-blocker issues by setting the target version to the new release.
+Assuming we're releasing version X, use below advanced filter in [submarine issue page](https://issues.apache.org/jira/projects/SUBMARINE). For instance, if we're releasing `0.3.0`.
+```
+project in ("Apache Submarine") AND "Target Version" = 0.3.0 AND statusCategory != Done
+```
+Click "tools"-> "bulk update" to edit all issues:
+1. Change the target version to X+1. Here it is `0.4.0` (If it doesn't exist, ask for the PMC's help to access [administer-versions](https://issues.apache.org/jira/plugins/servlet/project-config/SUBMARINE/administer-versions?status=no-filter) to add the new version).
+2. Add a comment to inform contributors. Like this. `Bulk update due to releasing 0.3.0. Please change it back if you think this is a blocker.`
+
+Do a double-check to confirm that there are no issues found with the above filter. And send mail to the developer list informing that we should mark "Target version" to `0.4.0` when creating new JIRAs.
+
+## 4. Tagging
+Once the JIRA is cleaned up, we can tag the candidate release with below steps:
+```
+export version=0.3.0
+export cversion=$version-RC0
+export tag=release-$cversion
+
+git tag -s $tag -m "Release candidate - $version"
+# Verify the tag is signed with your GPG key
+git tag -v $tag
+# Push the tag to apache repo
+git push origin $tag
+```
+
+## 5. Build Artifacts
+The submarine artifacts consists of GPG signed source code tarball, binary tarball and docker images.
+```
+cd dev-support/cicd/
+./create_release.sh $version $tag
+# Move the artifacts to a folder instead of /tmp/
+mv /tmp/submarine-release ~/
+```
+> Note: In here we use the `version` not the `cversion`.
+
+## 6. Upload Artifacts For Vote
+Before the uploading, we need to do some basic testing for the release candidates. For instance, build from the source tarball and run feature test using the binary tarball.
+
+### 6.1 Staging Source and Binary Tarball to self FTP server
+```
+cd ~/submarine-release
+sftp home.apache.org
+# if not exits, please mkdir
+cd public_html
+mkdir submarine-$cversion && cd $_
+put -r .
+exit
+```
+
+### 6.2 Staging Docker Images
+When doing release, the release manager might needs to package an artifact candidates in this docker image and public the image candidate for a vote.
+In this scenario, we can do this:
+
+Put submarine candidate artifacts to a folder like "~/releases/submarine-release"
+```
+$ ls $release_candidates_path
+submarine-dist-0.3.0-hadoop-2.9.tar.gz submarine-dist-0.3.0-src.tar.gz.asc
+submarine-dist-0.3.0-hadoop-2.9.tar.gz.asc submarine-dist-0.3.0-src.tar.gz.sha512
+submarine-dist-0.3.0-hadoop-2.9.tar.gz.sha512 submarine-dist-0.3.0-src.tar.gz
+```
+```
+export submarine_version=0.3.0
+export release_candidates_path=~/releases/submarine-release
+./build_mini-submarine.sh
+#docker run -it -h submarine-dev --net=bridge --privileged -P local/mini-submarine:0.3.0 /bin/bash
+docker tag local/mini-submarine:0.3.0 apache/submarine:mini-0.3.0-RC0
+```
+In the container, we can verify that the submarine jar version is the expected 0.3.0. Then we can upload this image with a "RC" tag for a vote.
+
+Note: if you don't have permission to push image to docker hub, create a jira ticket to request the push permission.
+
+Refer to https://issues.apache.org/jira/browse/INFRA-20364
+```
+docker push apache/submarine:mini-0.3.0-RC0
+```
+
+TODO: build the other images by manual.
+
+### 6.3 Publish Jars To Apache Maven Staging Repository
+```
+export GPG_PASSPHRASE=yourPassphase
+export ASF_USERID=yourApacheId
+export ASF_PASSWORD=yourApachePwd
+./publish_release.sh $version $tag
+```
+Then to view the staging repo, we can login the https://repository.apache.org with the apache id. Click the "Staging Repositories" in the left side of the web page. And click "orgapachesubmarine-1001", then you will see the details of the repo including the URI. The URI is like this:
+"https://repository.apache.org/content/repositories/orgapachesubmarine-1001"
+
+### 6.4 Call A Vote For The Release Candidate
+After the artifacts and images are staged, we can send a vote email to the community. It's recommended that we paste the URI of RC tag, RC release artifacts, docker images, maven staging repository and the KEYS.
+Refer to [here](https://www.mail-archive.com/dev@submarine.apache.org/msg01498.html) for an example.
+
+## 7. Release
+In several days if the [vote passes](http://hadoop.apache.org/bylaws#Decision+Making), we can publish the release. If the vote fails, then we need to start another RC from [cleanup](#3.-Clean-up-the-JIRA) to the [staging](#6.-Upload-Artifacts-For-Vote).
+
+1. Access [submarine project version page](https://issues.apache.org/jira/projects/SUBMARINE?selectedItem=com.atlassian.jira.jira-projects-plugin:release-page&status=unreleased). Click the version to be released, and then click the "Release" button. It will request the release date. We can fill it with the end-of-vote date.
+
+2. Tag the release
+```
+# please replace the version to the right version
+export version=0.3.0
+export tag=rel/release-$version
+git tag -s $tag -m "Submarine ${version} release"
+git push origin $tag
+```
+
+3. Copy release artifacts to apache dist server
+```
+svn co --depth immediates https://dist.apache.org/repos/dist apache-dist
+cd apache-dist
+svn update --set-depth infinity dev/submarine
+svn update --set-depth infinity release/submarine
+cd dev/submarine
+mkdir submarine-$version
+cp ~/submarine-release/* submarine-$version/
+svn add submarine-$version
+svn ci -m "Publishing the bits for submarine release ${version} to apache dist dev folder"
+cd ../../
+svn mv dev/submarine/submarine-$version release/submarine/
+svn ci -m "Publishing the bits for submarine release ${version}"
+```
+
+Usually binary tarball becomes larger than 300MB, so it cannot be directly uploaded to the distribution directory. We can use the dev directory (https://dist.apache.org/repos/dist/dev/submarine/) first and then move it to the distribution directory by svn move
+
+4. In [Nexus](https://repository.apache.org/), effect the release of artifacts by selecting the staged repository and then clicking Release. If there were multiple RCs, simply drop the staging repositories corresponding to failed RCs.
+
+5. Upload the docker images
+```
+docker tag apache/submarine:mini-0.3.0-RC0 apache/submarine:mini-0.3.0
+docker push apache/submarine:mini-0.3.0
+```
+
+6. Update the version in pom.xml
+```
+# if the new version a point release
+mvn versions:set -DgenerateBackupPoms=false -DnewVersion=X.(Y+1).Z-SNAPSHOT
+git commit -a -m "Preparing for X.(Y+1).Z development"
+```
+
+7. Wait 24 hours for release to propagate to mirrors.
+
+8. Update the website. The guide is [here](https://github.com/apache/submarine-site)
+```
+git clone https://github.com/apache/submarine-site.git
+cd submarine-site
+git checkout master
+# Edit download.md to add the new release content
+# The url of the binary and source tarball should be like
+# "https://www.apache.org/dyn/closer.cgi/submarine/submarine-0.3.0/submarine-dist-0.3.0-hadoop-2.9.tar.gz"
+# due to it will find a mirror server for different region.
+# The url of the signature and checksum should be like
+# "https://www.apache.org/dist/submarine/submarine-0.3.0/submarine-dist-0.3.0-hadoop-2.9.tar.gz.sha512)"
+# due to they're not mirrored from apache dist server.
+# For the release note web page, we need to create a MD file under "releases" directory
+# like "submarine-release-0.3.0.md". The count of issues can be found
+# from JIRA like "https://issues.apache.org/jira/projects/SUBMARINE/versions/12345556".
+# And the details of issues can also get from "Release Notes" in that page.
+cp release/submarine-release-0.3.0.md release/submarine-release-.md
+vim release/submarine-release-.md
+cd ..
+docker run -it -p 4000:4000 -v $PWD/submarine-site:/submarine-site hadoopsubmarine/submarine-website:1.0.0 bash
+cd /submarine-site
+bundle exec jekyll serve --watch --host=0.0.0.0
+# Open another terminal, you can edit MD files and refresh the webpage to see changes instantly.
+```
+
+9. Send announcements to the user and developer lists once the site changes are visible.
diff --git a/dev-support/cicd/README.md b/dev-support/cicd/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..4ed4c3a49454ac35a3f47246693edb3ec492ef13
--- /dev/null
+++ b/dev-support/cicd/README.md
@@ -0,0 +1,80 @@
+
+# CICD Introduction
+
+> Please note that cicd is a tool provided to submarine committers for PR merging and release. Only submarine committers have permission to execute.
+
+This cicd directory contains several scripts to ease code and release management. For how-to-release, check [here](./HowToRelease.md)
+
+To use them more easily, we provide a Docker image to help committer to handle tasks like committing code and release build.
+
+## Docker mode
+
+```
+./build_and_start_cicd_image.sh
+```
+
+Or
+
+```
+cd /dev-support/cicd
+docker build -t submarine-cicd .
+docker run -it --rm submarine-cicd
+```
+
+Jira username, password, apache id and apache username are required in the docker container. You can
+add them to the local environment variable.
+
+```
+vi ~/.bash_profile
+export JIRA_USERNAME='Your jira username'
+export JIRA_PASSWORD='Your jira password'
+export APACHE_ID='Your apache id' # Your apache email prefix
+export APACHE_NAME='Your apache name'
+```
+
+And you'll see output like below and then you can decide what to accomplish.
+```
+$ docker run -it -e JIRA_USERNAME="${JIRA_USERNAME}" -e JIRA_PASSWORD="${JIRA_PASSWORD}" -e APACHE_ID="${APACHE_ID}" -e APACHE_NAME="${APACHE_NAME}" -p 4000:4000 --rm submarine-cicd
+```
+
+The screen outputs the following information:
+
+```
+Menu:
+ 1. Merge PR
+ 2. Update Submarine Website
+Enter Menu ID:
+```
+
+As you can see, the Docker mode support several features like merging PR and updating the web site. Choose the task you need to do and follow the popup tip to go on.
+
+## Manual mode (Not Recommended)
+
+First, You need install `python 2.7.13` and `pip insall jira`
+
+### The Procedure of Merging PR
+
+1. mkdir ${work_dir}
+2. cd ${work_dir}
+3. git clone https://gitbox.apache.org/repos/asf/submarine.git
+4. cd submarine
+5. git remote rename origin apache
+6. git remote add apache-github https://github.com/apache/submarine.git
+7. optional: git config --local --add user.name {name}
+8. optional: git config --local --add user.email {username}@apache.org
+9. optional: echo -e "JIRA_USERNAME={jira_username}\nJIRA_PASSWORD={jira_password}" >> ~/.bashrc
+10. optional: source ~/.bashrc
+11. dev-support/cicd/merge_submarine_pr.py
+
diff --git a/dev-support/cicd/build_and_start_cicd_image.sh b/dev-support/cicd/build_and_start_cicd_image.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a43600faf6650cbadd97ea16442330a884842aa0
--- /dev/null
+++ b/dev-support/cicd/build_and_start_cicd_image.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# 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.
+set -euo pipefail
+
+printf "Building Submarine CI/CD Image.\n"
+docker build -t submarine-cicd .
+printf "Start Submarine CI/CD.\n"
+docker run -it --rm -p 4000:4000 submarine-cicd
diff --git a/dev-support/cicd/common_release.sh b/dev-support/cicd/common_release.sh
new file mode 100755
index 0000000000000000000000000000000000000000..517bc372ea938b7095ee6b76f50e88cbeda35260
--- /dev/null
+++ b/dev-support/cicd/common_release.sh
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+# common functions
+
+if [[ -z "${TAR:-}" ]]; then
+ TAR="/usr/bin/tar"
+fi
+
+if [[ -z "${SHASUM:-}" ]]; then
+ SHASUM="/usr/bin/shasum"
+fi
+
+if [[ -z "${WORKING_DIR:-}" ]]; then
+ WORKING_DIR="/tmp/submarine-release"
+fi
+
+DEBUG_SUBMARINE_SCRIPT=false
+if $DEBUG_SUBMARINE_SCRIPT; then
+ echo "DEBUGGING, skip remove ${WORKING_DIR}"
+else
+ echo "Cleaning up ${WORKING_DIR}"
+ rm -rf "${WORKING_DIR}"
+ mkdir "${WORKING_DIR}"
+fi
+
+# If set to 'yes', release script will deploy artifacts to SNAPSHOT repository.
+DO_SNAPSHOT='no'
+
+usage() {
+ echo "usage) $0 [Release version] [Branch or Tag]"
+ echo " ex. $0 0.6.0 v0.6.0"
+ exit 1
+}
+
+function git_clone() {
+ echo "Clone the source"
+ # clone source
+ git clone https://git-wip-us.apache.org/repos/asf/submarine.git "${WORKING_DIR}/submarine"
+
+ if [[ $? -ne 0 ]]; then
+ echo "Can not clone source repository"
+ exit 1
+ fi
+
+ cd "${WORKING_DIR}/submarine"
+ git checkout "${GIT_TAG}"
+ echo "Checked out ${GIT_TAG}"
+}
diff --git a/dev-support/cicd/create_release.sh b/dev-support/cicd/create_release.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fd83ef5ccb7b591ddbf9677183f55d8d0b5b10a0
--- /dev/null
+++ b/dev-support/cicd/create_release.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+#
+# 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 script helps making a release.
+# You need to specify release version and branch|tag name.
+#
+# Here are some helpful documents for the release.
+# http://www.apache.org/dev/release.html
+# http://www.apache.org/dev/release-publishing
+# http://www.apache.org/dev/release-signing.html
+
+set -euo pipefail
+
+BASEDIR="$(dirname "$0")"
+. "${BASEDIR}/common_release.sh"
+echo "${BASEDIR}/common_release.sh"
+
+if [[ $# -ne 2 ]]; then
+ usage
+fi
+
+for var in GPG_PASSPHRASE; do
+ if [[ -z "${!var:-}" ]]; then
+ echo "You need ${var} variable set"
+ exit 1
+ fi
+done
+
+RELEASE_VERSION="$1"
+GIT_TAG="$2"
+
+function compile_src_and_bin() {
+ cd ${WORKING_DIR}/submarine
+ echo "mvn versions:set -DnewVersion=${RELEASE_VERSION}"
+ mvn versions:set -DnewVersion="${RELEASE_VERSION}"
+ echo "mvn clean package -DskipTests -Psrc"
+ mvn clean package -DskipTests -Psrc
+ if [[ $? -ne 0 ]]; then
+ echo "Build failed. ${BUILD_FLAGS:-}"
+ exit 1
+ fi
+}
+
+function make_source_package() {
+ # create source package
+ cd ${WORKING_DIR}/submarine/submarine-dist/target
+ cd submarine-dist-*-src
+ # remove unneeded dir .github
+ rm -rf submarine-dist-${RELEASE_VERSION}-src/.github
+ ${TAR} cfz "submarine-dist-${RELEASE_VERSION}-src.tar.gz" "submarine-dist-${RELEASE_VERSION}-src"
+ mv "submarine-dist-${RELEASE_VERSION}-src.tar.gz" ${WORKING_DIR}
+ echo "Signing the source package"
+ cd "${WORKING_DIR}"
+ echo "${GPG_PASSPHRASE}" | gpg --passphrase-fd 0 --armor \
+ --output "submarine-dist-${RELEASE_VERSION}-src.tar.gz.asc" \
+ --detach-sig "${WORKING_DIR}/submarine-dist-${RELEASE_VERSION}-src.tar.gz"
+ ${SHASUM} -a 512 "submarine-dist-${RELEASE_VERSION}-src.tar.gz" > \
+ "${WORKING_DIR}/submarine-dist-${RELEASE_VERSION}-src.tar.gz.sha512"
+}
+
+function make_binary_release() {
+ R_DIR_NAME=submarine-dist-${RELEASE_VERSION}-hadoop-2.9
+ cd ${WORKING_DIR}/submarine/submarine-dist/target
+ mv "${R_DIR_NAME}.tar.gz" ${WORKING_DIR}
+ # sign bin package
+ cd ${WORKING_DIR}
+ echo "${GPG_PASSPHRASE}" | gpg --passphrase-fd 0 --armor \
+ --output "${R_DIR_NAME}.tar.gz.asc" \
+ --detach-sig "${R_DIR_NAME}.tar.gz"
+ ${SHASUM} -a 512 "${R_DIR_NAME}.tar.gz" > \
+ "${R_DIR_NAME}.tar.gz.sha512"
+}
+
+if [ -d "${WORKING_DIR}/submarine/submarine-dist/target" ]; then
+ if $DEBUG_SUBMARINE_SCRIPT; then
+ echo "DEBUGGING, skip re-building submarine"
+ fi
+else
+ git_clone
+ compile_src_and_bin
+fi
+
+make_source_package
+make_binary_release
+
+# remove non release files and dirs
+echo "Deleting ${WORKING_DIR}/submarine"
+rm -rf "${WORKING_DIR}/submarine"
+echo "Release files are created under ${WORKING_DIR}"
diff --git a/dev-support/cicd/entry.sh b/dev-support/cicd/entry.sh
new file mode 100755
index 0000000000000000000000000000000000000000..811683fc9b7e22ae3aac382442e7c64d56152e1a
--- /dev/null
+++ b/dev-support/cicd/entry.sh
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+# 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.
+set -euo pipefail
+# activate python 2.7.13 environment
+. ${PYTHON_VENV_PATH}/venv2.7/bin/activate
+
+function start_menu(){
+ printf "Menu:\n"
+ printf "\t1. Merge PR\n"
+ printf "\t2. Update Submarine Website\n"
+ read -p "Enter Menu ID:" menu_id
+ case $menu_id in
+ "1")
+ merge_pr
+ ;;
+ "2")
+ update_submarine_site
+ ;;
+ "*")
+ printf "unknown. Exiting."
+ ;;
+ esac
+}
+
+function merge_pr(){
+ printf "==== Merge PR Begin ====\n"
+ jira_name="n"
+ jira_pwd="p"
+ apache_id="id"
+ apache_name="name"
+
+ if [ -z "${JIRA_USERNAME:-}" ]; then
+ read -p "Enter Your Apache JIRA User name: " jira_name
+ else
+ jira_name=$JIRA_USERNAME
+ fi
+ echo "Got JIRA name: ${jira_name}"
+
+ if [ -z "${JIRA_PASSWORD:-}" ]; then
+ read -s -p "Enter Your Apache JIRA User passwd: " jira_pwd
+ else
+ jira_pwd=$JIRA_PASSWORD
+ fi
+
+ if [ -z "${APACHE_ID:-}" ]; then
+ printf "\n"
+ read -p "Enter Your Apache committer ID: " apache_id
+ else
+ apache_id=$APACHE_ID
+ fi
+ echo "Got Apache ID: ${apache_id}"
+
+ if [ -z "${APACHE_NAME:-}" ]; then
+ read -p "Enter Your Apache committer name: " apache_name
+ else
+ apache_name=$APACHE_NAME
+ fi
+ echo "Got Apache name: ${apache_name}"
+
+ cd $SUBMARINE_HOME
+ git checkout master
+ git pull
+ git config user.name "${apache_name}"
+ git config user.email "${apache_id}@apache.org"
+ export JIRA_USERNAME=${jira_name}
+ export JIRA_PASSWORD=${jira_pwd}
+ python dev-support/cicd/merge_submarine_pr.py
+ printf "==== Merge PR END ====\n"
+}
+
+function update_submarine_site(){
+ printf "==== Update Submarine Site Begin ====\n"
+ apache_id="id"
+ apache_name="name"
+
+ if [ -z "${APACHE_ID:-}" ]; then
+ printf "\n"
+ read -p "Enter Your Apache committer ID: " apache_id
+ else
+ apache_id=$APACHE_ID
+ fi
+ echo "Got Apache ID: ${apache_id}"
+
+ if [ -z "${APACHE_NAME:-}" ]; then
+ read -p "Enter Your Apache committer name: " apache_name
+ else
+ apache_name=$APACHE_NAME
+ fi
+ echo "Got Apache name: ${apache_name}"
+
+ cd $SUBMARINE_SITE
+ git checkout master
+ git pull
+ git config user.name "${apache_name}"
+ git config user.email "${apache_id}@apache.org"
+ git config credential.helper store
+ bundle update
+ bundle exec jekyll serve --watch --host=0.0.0.0 > /tmp/jekyll.log 2>&1 &
+ echo "==== Please use vim to edit md files and check http://localhost:4000/ for the update ===="
+ while true; do
+ echo "==== Edit Mode: Type 'exit' when you finish the changes (you don't need to perform git commit/push). ===="
+ bash
+ read -p "Have you finished updating the MD files? y/n/quit " commit
+ case $commit in
+ "y")
+ echo "Start committing changes.."
+ cd $SUBMARINE_SITE
+ git add .
+ git status
+ read -p "Please input the commit message: " message
+ git commit -m "${message} (master branch)"
+ git push origin master
+ cp -r _site /_site
+ git checkout asf-site
+ cp -r /_site/* ./
+ git add .
+ git status
+ git commit -m "${message} (asf-site branch)"
+ git push origin asf-site
+ echo "Exiting edit mode.."
+ break
+ ;;
+ "n")
+ continue
+ ;;
+ "quit")
+ printf "Exiting edit mode.."
+ break
+ ;;
+ "q")
+ printf "Exiting edit mode.."
+ break
+ ;;
+ "*")
+ printf "Unknown. Exiting edit mode.."
+ break
+ ;;
+ esac
+ done
+ printf "\n"
+ printf "==== Update Submarine Site END ====\n"
+ echo "==== Enter shell again incase any unexpected error happens ===="
+ bash
+ echo "Exiting CICD.."
+}
+
+start_menu
+deactivate
diff --git a/dev-support/cicd/merge_submarine_pr.py b/dev-support/cicd/merge_submarine_pr.py
new file mode 100755
index 0000000000000000000000000000000000000000..7b5e57c616793f451fb449e8a759b7260e9de702
--- /dev/null
+++ b/dev-support/cicd/merge_submarine_pr.py
@@ -0,0 +1,359 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+# Utility for creating well-formed pull request merges and pushing them to Apache.
+# usage: ./merge-submarine-pr.py (see config env vars below)
+#
+# This utility assumes you already have local a Submarine git folder and that you
+# have added remotes corresponding to both (i) the github apache Submarine
+# mirror and (ii) the apache git repo.
+
+import json
+import os
+import re
+import subprocess
+import sys
+import urllib2
+
+try:
+ import jira.client
+ JIRA_IMPORTED = True
+except ImportError:
+ JIRA_IMPORTED = False
+
+# Location of your Submarine git development area
+SUBMARINE_HOME = os.environ.get("SUBMARINE_HOME", os.getcwd())
+# Remote name which points to the Github site
+PR_REMOTE_NAME = os.environ.get("PR_REMOTE_NAME", "apache-github")
+# Remote name which points to Apache git
+PUSH_REMOTE_NAME = os.environ.get("PUSH_REMOTE_NAME", "apache")
+# ASF JIRA username
+JIRA_USERNAME = os.environ.get("JIRA_USERNAME", "you-jira-user-name")
+# ASF JIRA password
+JIRA_PASSWORD = os.environ.get("JIRA_PASSWORD", "you-jira-password")
+
+GITHUB_BASE = "https://github.com/apache/submarine/pull"
+GITHUB_API_BASE = "https://api.github.com/repos/apache/submarine"
+JIRA_BASE = "https://issues.apache.org/jira/browse"
+JIRA_API_BASE = "https://issues.apache.org/jira"
+# Prefix added to temporary branches
+BRANCH_PREFIX = "PR_TOOL"
+
+os.chdir(SUBMARINE_HOME)
+
+
+def get_json(url):
+ try:
+ return json.load(urllib2.urlopen(url))
+ except urllib2.HTTPError as e:
+ print "Unable to fetch URL, exiting: %s" % url
+ sys.exit(-1)
+
+
+def fail(msg):
+ print msg
+ clean_up()
+ sys.exit(-1)
+
+
+def run_cmd(cmd):
+ print cmd
+ if isinstance(cmd, list):
+ return subprocess.check_output(cmd)
+ else:
+ return subprocess.check_output(cmd.split(" "))
+
+
+def continue_maybe(prompt):
+ result = raw_input("\n%s (y/n): " % prompt)
+ if result.lower() != "y":
+ fail("Okay, exiting")
+
+
+original_head = run_cmd("git rev-parse HEAD")[:8]
+
+
+def clean_up():
+ print "Restoring head pointer to %s" % original_head
+ run_cmd("git checkout %s" % original_head)
+
+ branches = run_cmd("git branch").replace(" ", "").split("\n")
+
+ for branch in filter(lambda x: x.startswith(BRANCH_PREFIX), branches):
+ print "Deleting local branch %s" % branch
+ run_cmd("git branch -D %s" % branch)
+
+
+# merge the requested PR and return the merge hash
+def merge_pr(pr_num, target_ref):
+ pr_branch_name = "%s_MERGE_PR_%s" % (BRANCH_PREFIX, pr_num)
+ target_branch_name = "%s_MERGE_PR_%s_%s" % (BRANCH_PREFIX, pr_num, target_ref.upper())
+ run_cmd("git fetch %s pull/%s/head:%s" % (PR_REMOTE_NAME, pr_num, pr_branch_name))
+ run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, target_ref, target_branch_name))
+ run_cmd("git checkout %s" % target_branch_name)
+
+ had_conflicts = False
+ try:
+ run_cmd(['git', 'merge', pr_branch_name, '--squash'])
+ except Exception as e:
+ msg = "Error merging: %s\nWould you like to manually fix-up this merge?" % e
+ continue_maybe(msg)
+ msg = "Okay, please fix any conflicts and 'git add' conflicting files... Finished?"
+ continue_maybe(msg)
+ had_conflicts = True
+
+ commit_authors = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
+ '--pretty=format:%an <%ae>']).split("\n")
+ commit_date = run_cmd(['git', 'log', '%s' % pr_branch_name, '-1',
+ '--pretty=format:%ad'])
+ distinct_authors = sorted(set(commit_authors),
+ key=lambda x: commit_authors.count(x), reverse=True)
+ primary_author = distinct_authors[0]
+ commits = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
+ '--pretty=format:%h [%an] %s']).split("\n\n")
+
+ merge_message_flags = []
+
+ merge_message_flags += ["-m", title]
+ if body is not None:
+ # We remove @ symbols from the body to avoid triggering e-mails
+ # to people every time someone creates a public fork of Submarine.
+ if isinstance(body, unicode):
+ merge_message_flags += ["-m", body.encode("utf-8").replace("@", "")]
+ else:
+ merge_message_flags += ["-m", body.replace("@", "")]
+
+ authors = "\n".join(["Author: %s" % a for a in distinct_authors])
+
+ merge_message_flags += ["-m", authors]
+
+ if had_conflicts:
+ committer_name = run_cmd("git config --get user.name").strip()
+ committer_email = run_cmd("git config --get user.email").strip()
+ message = "This patch had conflicts when merged, resolved by\nCommitter: %s <%s>" % (
+ committer_name, committer_email)
+ merge_message_flags += ["-m", message]
+
+ # The string "Closes #%s" string is required for GitHub to correctly close the PR
+ merge_message_flags += [
+ "-m",
+ "Closes #%s from %s and squashes the following commits:" % (pr_num, pr_repo_desc)]
+ for c in commits:
+ merge_message_flags += ["-m", c]
+
+ run_cmd(['git', 'commit', '--author="%s"' % primary_author, '--date="%s"' % commit_date] + merge_message_flags)
+
+ continue_maybe("Merge complete (local ref %s). Push to %s?" % (
+ target_branch_name, PUSH_REMOTE_NAME))
+
+ try:
+ run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, target_branch_name, target_ref))
+ except Exception as e:
+ clean_up()
+ fail("Exception while pushing: %s" % e)
+
+ merge_hash = run_cmd("git rev-parse %s" % target_branch_name)[:8]
+ clean_up()
+ print("Pull request #%s merged!" % pr_num)
+ print("Merge hash: %s" % merge_hash)
+ return merge_hash
+
+
+def cherry_pick(pr_num, merge_hash, default_branch):
+ pick_ref = raw_input("Enter a branch name [%s]: " % default_branch)
+ if pick_ref == "":
+ pick_ref = default_branch
+
+ pick_branch_name = "%s_PICK_PR_%s_%s" % (BRANCH_PREFIX, pr_num, pick_ref.upper())
+
+ run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, pick_ref, pick_branch_name))
+ run_cmd("git checkout %s" % pick_branch_name)
+
+ try:
+ run_cmd("git cherry-pick -sx %s" % merge_hash)
+ except Exception as e:
+ msg = "Error cherry-picking: %s\nWould you like to manually fix-up this merge?" % e
+ continue_maybe(msg)
+ msg = "Okay, please fix any conflicts and finish the cherry-pick. Finished?"
+ continue_maybe(msg)
+
+ continue_maybe("Pick complete (local ref %s). Push to %s?" % (
+ pick_branch_name, PUSH_REMOTE_NAME))
+
+ try:
+ run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, pick_branch_name, pick_ref))
+ except Exception as e:
+ clean_up()
+ fail("Exception while pushing: %s" % e)
+
+ pick_hash = run_cmd("git rev-parse %s" % pick_branch_name)[:8]
+ clean_up()
+
+ print("Pull request #%s picked into %s!" % (pr_num, pick_ref))
+ print("Pick hash: %s" % pick_hash)
+ return pick_ref
+
+
+def fix_version_from_branch(branch, versions):
+ # Note: Assumes this is a sorted (newest->oldest) list of un-released versions
+ if branch == "master":
+ return versions[0]
+ else:
+ branch_ver = branch.replace("branch-", "")
+ return filter(lambda x: x.name.startswith(branch_ver), versions)[-1]
+
+
+def resolve_jira_issue(merge_branches, comment, default_jira_id=""):
+ asf_jira = jira.client.JIRA({'server': JIRA_API_BASE},
+ basic_auth=(JIRA_USERNAME, JIRA_PASSWORD))
+
+ jira_id = raw_input("Enter a JIRA id [%s]: " % default_jira_id)
+ if jira_id == "":
+ jira_id = default_jira_id
+
+ try:
+ issue = asf_jira.issue(jira_id)
+ except Exception as e:
+ fail("ASF JIRA could not find %s\n%s" % (jira_id, e))
+
+ cur_status = issue.fields.status.name
+ cur_summary = issue.fields.summary
+ cur_assignee = issue.fields.assignee
+ if cur_assignee is None:
+ cur_assignee = "NOT ASSIGNED!!!"
+ else:
+ cur_assignee = cur_assignee.displayName
+
+ if cur_status == "Resolved" or cur_status == "Closed":
+ fail("JIRA issue %s already has status '%s'" % (jira_id, cur_status))
+ print ("=== JIRA %s ===" % jira_id)
+ print ("summary\t\t%s\nassignee\t%s\nstatus\t\t%s\nurl\t\t%s/%s\n" % (
+ cur_summary, cur_assignee, cur_status, JIRA_BASE, jira_id))
+
+ versions = asf_jira.project_versions("SUBMARINE")
+ versions = sorted(versions, key=lambda x: x.name, reverse=True)
+ versions = filter(lambda x: x.raw['released'] is False, versions)
+ # Consider only x.y.z versions
+ versions = filter(lambda x: re.match('\d+\.\d+\.\d+', x.name), versions)
+
+ default_fix_versions = map(lambda x: fix_version_from_branch(x, versions).name, merge_branches)
+ for v in default_fix_versions:
+ # Handles the case where we have forked a release branch but not yet made the release.
+ # In this case, if the PR is committed to the master branch and the release branch, we
+ # only consider the release branch to be the fix version. E.g. it is not valid to have
+ # both 1.1.0 and 1.0.0 as fix versions.
+ (major, minor, patch) = v.split(".")
+ if patch == "0":
+ previous = "%s.%s.%s" % (major, int(minor) - 1, 0)
+ if previous in default_fix_versions:
+ default_fix_versions = filter(lambda x: x != v, default_fix_versions)
+ default_fix_versions = ",".join(default_fix_versions)
+
+ fix_versions = raw_input("Enter comma-separated fix version(s) [%s]: " % default_fix_versions)
+ if fix_versions == "":
+ fix_versions = default_fix_versions
+ fix_versions = fix_versions.replace(" ", "").split(",")
+
+ def get_version_json(version_str):
+ return filter(lambda v: v.name == version_str, versions)[0].raw
+
+ jira_fix_versions = map(lambda v: get_version_json(v), fix_versions)
+
+ resolve = filter(lambda a: a['name'] == "Resolve Issue", asf_jira.transitions(jira_id))[0]
+ asf_jira.transition_issue(
+ jira_id, resolve["id"], fixVersions=jira_fix_versions, comment=comment)
+
+ print "Successfully resolved %s with fixVersions=%s!" % (jira_id, fix_versions)
+
+
+def resolve_jira_issues(title, merge_branches, comment):
+ jira_ids = re.findall("SUBMARINE-[0-9]{3,5}", title)
+
+ if len(jira_ids) == 0:
+ resolve_jira_issue(merge_branches, comment)
+ for jira_id in jira_ids:
+ resolve_jira_issue(merge_branches, comment, jira_id)
+
+
+#branches = get_json("%s/branches" % GITHUB_API_BASE)
+#branch_names = filter(lambda x: x.startswith("branch-"), [x['name'] for x in branches])
+# Assumes branch names can be sorted lexicographically
+#latest_branch = sorted(branch_names, reverse=True)[0]
+latest_branch = "master"
+
+pr_num = raw_input("Which pull request would you like to merge? (e.g. 23): ")
+pr = get_json("%s/pulls/%s" % (GITHUB_API_BASE, pr_num))
+pr_events = get_json("%s/issues/%s/events" % (GITHUB_API_BASE, pr_num))
+
+url = pr["url"]
+title = pr["title"]
+body = pr["body"]
+target_ref = pr["base"]["ref"]
+user_login = pr["user"]["login"]
+base_ref = pr["head"]["ref"]
+pr_repo_desc = "%s/%s" % (user_login, base_ref)
+
+# Merged pull requests don't appear as merged in the GitHub API;
+# Instead, they're closed by asfgit.
+merge_commits = \
+ [e for e in pr_events if e["actor"]["login"] == "asfgit" and e["event"] == "closed"]
+
+if merge_commits:
+ merge_hash = merge_commits[0]["commit_id"]
+ message = get_json("%s/commits/%s" % (GITHUB_API_BASE, merge_hash))["commit"]["message"]
+
+ print "Pull request %s has already been merged, assuming you want to backport" % pr_num
+ commit_is_downloaded = run_cmd(['git', 'rev-parse', '--quiet', '--verify',
+ "%s^{commit}" % merge_hash]).strip() != ""
+ if not commit_is_downloaded:
+ fail("Couldn't find any merge commit for #%s, you may need to update HEAD." % pr_num)
+
+ print "Found commit %s:\n%s" % (merge_hash, message)
+ cherry_pick(pr_num, merge_hash, latest_branch)
+ sys.exit(0)
+
+if not bool(pr["mergeable"]):
+ msg = "Pull request %s is not mergeable in its current form.\n" % pr_num + \
+ "Continue? (experts only!)"
+ continue_maybe(msg)
+
+print ("\n=== Pull Request #%s ===" % pr_num)
+print ("title\t%s\nsource\t%s\ntarget\t%s\nurl\t%s" % (
+ title, pr_repo_desc, target_ref, url))
+continue_maybe("Proceed with merging pull request #%s?" % pr_num)
+
+merged_refs = [target_ref]
+
+merge_hash = merge_pr(pr_num, target_ref)
+
+pick_prompt = "Would you like to pick %s into another branch?" % merge_hash
+while raw_input("\n%s (y/n): " % pick_prompt).lower() == "y":
+ merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, latest_branch)]
+
+if JIRA_IMPORTED:
+ if JIRA_USERNAME and JIRA_PASSWORD:
+ continue_maybe("Would you like to update an associated JIRA?")
+ jira_comment = "Issue resolved by pull request %s\n[%s/%s]" % (pr_num, GITHUB_BASE, pr_num)
+ resolve_jira_issues(title, merged_refs, jira_comment)
+ else:
+ print "JIRA_USERNAME and JIRA_PASSWORD not set"
+ print "Exiting without trying to close the associated JIRA."
+else:
+ print "Could not find jira library. Run 'sudo pip install jira' to install."
+ print "Exiting without trying to close the associated JIRA."
diff --git a/dev-support/cicd/publish_release.sh b/dev-support/cicd/publish_release.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ac620f14325962097984f2b963649ea53e62e67a
--- /dev/null
+++ b/dev-support/cicd/publish_release.sh
@@ -0,0 +1,178 @@
+#!/usr/bin/env bash
+#
+# 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 script helps publishing release to maven.
+# You need to specify release version and branch|tag name.
+#
+# Here's some helpful documents for the release.
+# http://www.apache.org/dev/publishing-maven-artifacts.html
+set -euo pipefail
+BASEDIR="$(dirname "$0")"
+. "${BASEDIR}/common_release.sh"
+
+if [[ $# -ne 2 ]]; then
+ usage
+fi
+
+for var in GPG_PASSPHRASE ASF_USERID ASF_PASSWORD; do
+ if [[ -z "${!var:-}" ]]; then
+ echo "You need ${var} variable set"
+ exit 1
+ fi
+done
+
+export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512m"
+RED='\033[0;31m'
+NC='\033[0m' # No Color
+
+RELEASE_VERSION="$1"
+GIT_TAG="$2"
+if [[ $RELEASE_VERSION == *"SNAPSHOT"* ]]; then
+ DO_SNAPSHOT="yes"
+fi
+
+NEXUS_STAGING="https://repository.apache.org/service/local/staging"
+# Get this from apache infra admin
+NEXUS_PROFILE="2525cde13fad2a"
+
+function cleanup() {
+ echo "Remove working directory and maven local repository"
+ rm -rf ${WORKING_DIR}
+}
+
+function curl_error() {
+ ret=${1}
+ if [[ $ret -ne 0 ]]; then
+ echo "curl response code is: ($ret)"
+ echo "See https://curl.haxx.se/libcurl/c/libcurl-errors.html to know the detailed cause of error."
+ echo -e "${RED}Failed to publish maven artifact to staging repository."
+ echo -e "IMPORTANT: You will have to re-run publish_release.sh to complete maven artifact publish.${NC}"
+ cleanup
+ exit 1
+ fi
+}
+
+
+#
+# Publishing Apache Submarine artifact to Apache snapshot repository.
+#
+function publish_snapshot_to_maven() {
+ cd "${WORKING_DIR}/submarine"
+ echo "Deploying Apache Submarine $RELEASE_VERSION version to snapshot repository."
+
+ if [[ ! $RELEASE_VERSION == *"SNAPSHOT"* ]]; then
+ echo "ERROR: Snapshots must have a version containing 'SNAPSHOT'"
+ echo "ERROR: You gave version '$RELEASE_VERSION'"
+ exit 1
+ fi
+
+ tmp_repo="$(mktemp -d /tmp/submarine-repo-XXXXX)"
+ mvn versions:set -DnewVersion=$RELEASE_VERSION
+ tmp_settings="tmp-settings.xml"
+ echo "" > $tmp_settings
+ echo "apache.snapshots.https$ASF_USERID" >> $tmp_settings
+ echo "$ASF_PASSWORD" >> $tmp_settings
+ echo "" >> $tmp_settings
+
+ mvn --settings $tmp_settings -Dmaven.repo.local="${tmp_repo}" -DskipTests deploy
+
+ rm $tmp_settings
+ rm -rf $tmp_repo
+}
+
+function publish_to_maven() {
+ cd "${WORKING_DIR}/submarine"
+ # Force release version
+ mvn versions:set -DnewVersion="${RELEASE_VERSION}"
+
+ # Using Nexus API documented here:
+ # https://support.sonatype.com/hc/en-us/articles/213465868-Uploading-to-a-Staging-Repository-via-REST-API
+ echo "Creating Nexus staging repository"
+ repo_request="Apache Submarine ${RELEASE_VERSION}"
+ out="$(curl -X POST -d "${repo_request}" -u "${ASF_USERID}:${ASF_PASSWORD}" \
+ -H 'Content-Type:application/xml' -v \
+ "${NEXUS_STAGING}/profiles/${NEXUS_PROFILE}/start")"
+ create_ret=$?
+ curl_error $create_ret
+ staged_repo_id="$(echo ${out} | sed -e 's/.*\(orgapachesubmarine-[0-9]\{4\}\).*/\1/')"
+ if [[ -z "${staged_repo_id}" ]]; then
+ echo "Fail to create staging repository"
+ exit 1
+ fi
+
+ echo "Created Nexus staging repository: ${staged_repo_id}"
+
+ rm -rf $HOME/.m2/repository/org/apache/submarine
+
+ # build and install to local
+ echo "mvn clean install -DskipTests"
+ mvn clean install -DskipTests
+ if [[ $? -ne 0 ]]; then
+ echo "Mvn install failed."
+ exit 1
+ fi
+
+ pushd "${HOME}/.m2/repository/org/apache/submarine"
+ find . -type f | grep -v '\.jar$' | grep -v '\.pom$' |grep -v '\.war$' | xargs rm
+
+ echo "Creating hash and signature files"
+ for file in $(find . -type f); do
+ echo "${GPG_PASSPHRASE}" | gpg --passphrase-fd 0 --output "${file}.asc" \
+ --detach-sig --armor "${file}"
+ if [ $(command -v md5) ]; then
+ # Available on OS X; -q to keep only hash
+ md5 -q $file > $file.md5
+ else
+ # Available on Linux; cut to keep only hash
+ md5sum $file | cut -f1 -d' ' > $file.md5
+ fi
+ ${SHASUM} -a 1 "${file}" | cut -f1 -d' ' > "${file}.sha1"
+ done
+
+ nexus_upload="${NEXUS_STAGING}/deployByRepositoryId/${staged_repo_id}"
+ echo "Uploading files to ${nexus_upload}"
+ for file in $(find . -type f); do
+ # strip leading ./
+ file_short="$(echo "${file}" | sed -e 's/\.\///')"
+ dest_url="${nexus_upload}/org/apache/submarine/$file_short"
+ echo " Uploading ${file_short}"
+ curl -u "${ASF_USERID}:${ASF_PASSWORD}" --upload-file "${file_short}" "${dest_url}"
+ upload_ret=$?
+ curl_error $upload_ret
+ done
+
+ echo "Closing nexus staging repository"
+ repo_request="${staged_repo_id}Apache Submarine ${RELEASE_VERSION}"
+ out="$(curl -X POST -d "${repo_request}" -u "${ASF_USERID}:${ASF_PASSWORD}" \
+ -H 'Content-Type:application/xml' -v \
+ "${NEXUS_STAGING}/profiles/${NEXUS_PROFILE}/finish")"
+ close_ret=$?
+ curl_error $close_ret
+ echo "Closed Nexus staging repository: ${staged_repo_id}"
+ popd
+ echo "Complete publishing maven artifacts to apache staging repository"
+ echo "Once release candidate pass the vote, do not forget to hit the release button in https://repository.apache.org"
+}
+
+git_clone
+if [[ "${DO_SNAPSHOT:-}" == 'yes' ]]; then
+ publish_snapshot_to_maven
+else
+ publish_to_maven
+fi
+cleanup
diff --git a/dev-support/docker-images/database/Dockerfile b/dev-support/docker-images/database/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..996bd23c61398f6fb11ac8a6ba35a33c97b16e96
--- /dev/null
+++ b/dev-support/docker-images/database/Dockerfile
@@ -0,0 +1,26 @@
+# 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.
+
+FROM submarinehub/mysql:5.7.27
+MAINTAINER Apache Software Foundation
+
+ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
+
+ADD database/* /tmp/database/
+ADD startup.sh ${AUTO_RUN_DIR}/
+RUN chmod +x ${AUTO_RUN_DIR}/startup.sh
+
+# mysql port
+EXPOSE 3306
diff --git a/dev-support/docker-images/database/build.sh b/dev-support/docker-images/database/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d87c6684129cb3f0a24b857f254754a69a4f5cee
--- /dev/null
+++ b/dev-support/docker-images/database/build.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euxo pipefail
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ PWD=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ PWD=$(dirname ${BASH_SOURCE-$0})
+fi
+export CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+SUBMARINE_HOME=${CURRENT_PATH}/../../..
+
+SUBMARINE_VERSION="0.5.0"
+SUBMARINE_IMAGE_NAME="apache/submarine:database-${SUBMARINE_VERSION}"
+
+cp -rf "${SUBMARINE_HOME}/docs/database" "${CURRENT_PATH}"
+
+# build image
+echo "Start building the ${SUBMARINE_IMAGE_NAME} docker image ..."
+cd ${CURRENT_PATH}
+docker build -t ${SUBMARINE_IMAGE_NAME} .
+
+# clean template file
+rm -rf ${CURRENT_PATH}/database
diff --git a/dev-support/docker-images/database/startup.sh b/dev-support/docker-images/database/startup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..884fab6008def948a548f3e47bf16308d057688c
--- /dev/null
+++ b/dev-support/docker-images/database/startup.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+# 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.
+
+mysql -uroot -p$MYSQL_ROOT_PASSWORD <> /etc/environment && \
+ echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
+ echo "LANG=en_US.UTF-8" > /etc/locale.conf && \
+ locale-gen en_US.UTF-8
+
+ENV NB_USER=$NB_USER \
+ NB_UID=$NB_UID \
+ NB_PREFIX=$NB_PREFIX \
+ NB_PORT=$NB_PORT \
+ CONDA_DIR=/opt/conda \
+ LANG=en_US.UTF-8 \
+ LC_ALL=en_US.UTF-8 \
+ LANGUAGE=en_US.UTF-8
+ENV PATH=$CONDA_DIR/bin:$PATH \
+ HOME=/home/$NB_USER
+
+# Create NB_USER user with UID=1000 and in the 'users' group
+RUN useradd -M -s /bin/bash -N -u $NB_UID $NB_USER && \
+ chown -R ${NB_USER}:users /usr/local/bin && \
+ mkdir -p $HOME && \
+ chown -R ${NB_USER}:users ${HOME} && \
+ mkdir -p ${CONDA_DIR} && \
+ chown -R ${NB_USER}:users ${CONDA_DIR} && \
+ chmod g+w /etc/passwd
+
+# Add Tini
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
+RUN mv /tini /usr/local/bin/tini && chmod +x /usr/local/bin/tini
+
+# Install conda
+USER $NB_UID
+ARG PYTHON_VERSION=default
+ENV MINICONDA_VERSION=4.8.3 \
+ MINICONDA_MD5=751786b92c00b1aeae3f017b781018df \
+ CONDA_VERSION=4.8.3
+
+WORKDIR /tmp
+RUN wget --quiet https://repo.continuum.io/miniconda/Miniconda3-py37_${MINICONDA_VERSION}-Linux-x86_64.sh && \
+ echo "${MINICONDA_MD5} *Miniconda3-py37_${MINICONDA_VERSION}-Linux-x86_64.sh" | md5sum -c - && \
+ /bin/bash Miniconda3-py37_${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR && \
+ rm Miniconda3-py37_${MINICONDA_VERSION}-Linux-x86_64.sh && \
+ echo "conda ${CONDA_VERSION}" >> $CONDA_DIR/conda-meta/pinned && \
+ conda config --system --prepend channels conda-forge && \
+ conda config --system --set auto_update_conda false && \
+ conda config --system --set show_channel_urls true && \
+ conda config --system --set channel_priority strict && \
+ if [ ! $PYTHON_VERSION = 'default' ]; then conda install --yes python=$PYTHON_VERSION; fi && \
+ conda list python | grep '^python ' | tr -s ' ' | cut -d '.' -f 1,2 | sed 's/$/.*/' >> $CONDA_DIR/conda-meta/pinned && \
+ conda clean --all -f -y && \
+ rm -rf /home/$NB_USER/.cache/yarn
+
+# Install latest sumbarine python sdk and notebook
+RUN pip install notebook==6.1.3 && \
+ git clone https://github.com/apache/submarine && \
+ pip install submarine/submarine-sdk/pysubmarine && \
+ cp submarine/submarine-sdk/pysubmarine/example/submarine_experiment_sdk.ipynb $HOME && \
+ cp -r submarine/submarine-sdk/pysubmarine/example/{data,deepfm_example.ipynb,deepfm.json} $HOME && \
+ rm submarine -rf
+
+
+
+EXPOSE $NB_PORT
+ENTRYPOINT ["tini", "-g", "--"]
+CMD ["start-notebook.sh"]
+COPY --chown=${NB_USER}:users start-notebook.sh /usr/local/bin
+WORKDIR ${HOME}
diff --git a/dev-support/docker-images/jupyter/build.sh b/dev-support/docker-images/jupyter/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e2b083ea3e842c393c260792c134b16e76e784d3
--- /dev/null
+++ b/dev-support/docker-images/jupyter/build.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euxo pipefail
+
+JUPYTER_IMAGE="apache/submarine:jupyter-notebook-0.5.0"
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ PWD=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ PWD=$(dirname ${BASH_SOURCE-$0})
+fi
+export CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+SUBMARINE_HOME=${CURRENT_PATH}/../../..
+
+# build image
+echo "Start building the ${JUPYTER_IMAGE} docker image ..."
+cd ${CURRENT_PATH}
+docker build -t ${JUPYTER_IMAGE} .
diff --git a/dev-support/docker-images/jupyter/start-notebook.sh b/dev-support/docker-images/jupyter/start-notebook.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fce5e33981ac9f488d14b78aab70cb7849f3b36a
--- /dev/null
+++ b/dev-support/docker-images/jupyter/start-notebook.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# description: Start and stop daemon script for.
+#
+
+set -euo pipefail
+
+# Install conda dependency
+if [[ -n "${INSTALL_ENVIRONMENT_COMMAND:-}" ]]; then
+ /bin/bash -c "${INSTALL_ENVIRONMENT_COMMAND}"
+fi
+
+NOTEBOOK_ARGS="--ip=0.0.0.0 --no-browser --allow-root --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*'"
+NB_USER="${NB_USER:-"jovyan"}"
+NB_PREFIX="${NB_PREFIX:-"/"}"
+NB_PORT="${NB_PORT:-8888}"
+
+if [[ -n "${NB_USER}" ]]; then
+ NOTEBOOK_ARGS="--notebook-dir=/home/${NB_USER} ${NOTEBOOK_ARGS}"
+fi
+
+if [[ -n "${NB_PORT}" ]]; then
+ NOTEBOOK_ARGS="--port=${NB_PORT} ${NOTEBOOK_ARGS}"
+fi
+
+if [[ -n "${NB_PREFIX}" ]]; then
+ NOTEBOOK_ARGS="--NotebookApp.base_url=${NB_PREFIX} ${NOTEBOOK_ARGS}"
+fi
+
+/bin/bash -c "jupyter notebook ${NOTEBOOK_ARGS}"
diff --git a/dev-support/docker-images/operator/Dockerfile b/dev-support/docker-images/operator/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d1a0080d24ed840828d00d0dca760420df92bdd5
--- /dev/null
+++ b/dev-support/docker-images/operator/Dockerfile
@@ -0,0 +1,27 @@
+# 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.
+
+FROM alpine:3.10
+MAINTAINER Apache Software Foundation
+
+# If you are in China, enabling the following two lines of code can speed up the build of the image, but it may cause failure in travis.
+# So when submitting the code, please make sure the following 2 lines of code are in a commented state
+# RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.10/main" > /etc/apk/repositories
+# RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.10/community" >> /etc/apk/repositories
+
+RUN apk add tzdata --no-cache
+ADD ./tmp/submarine-operator /usr/local/bin/submarine-operator
+
+ENTRYPOINT [ "/usr/local/bin/submarine-operator" ]
diff --git a/dev-support/docker-images/operator/build.sh b/dev-support/docker-images/operator/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5adbfe6bb7e78d1d0a99aa62658d45be32938469
--- /dev/null
+++ b/dev-support/docker-images/operator/build.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euxo pipefail
+
+SUBMARINE_VERSION=0.5.0
+SUBMARINE_IMAGE_NAME="apache/submarine:operator-${SUBMARINE_VERSION}"
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ PWD=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ PWD=$(dirname ${BASH_SOURCE-$0})
+fi
+export CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+export SUBMARINE_HOME=${CURRENT_PATH}/../../..
+
+if [ ! -d "${SUBMARINE_HOME}/submarine-cloud/bin" ]; then
+ mkdir "${SUBMARINE_HOME}/submarine-cloud/bin"
+fi
+submarine_operator_exists=$(find -L "${SUBMARINE_HOME}/submarine-cloud/bin" -name "submarine-operator")
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_operator_exists}" ]]; then
+ cd "${SUBMARINE_HOME}/submarine-cloud"
+ mvn package
+fi
+
+mkdir -p "${CURRENT_PATH}/tmp"
+cp ${SUBMARINE_HOME}/submarine-cloud/bin/submarine-operator "${CURRENT_PATH}/tmp"
+
+# build image
+cd ${CURRENT_PATH}
+echo "Start building the ${SUBMARINE_IMAGE_NAME} docker image ..."
+docker build -t ${SUBMARINE_IMAGE_NAME} .
+
+# clean temp file
+rm -rf "${CURRENT_PATH}/tmp"
diff --git a/dev-support/docker-images/submarine/Dockerfile b/dev-support/docker-images/submarine/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..792080ab9f49022da8eba67fbcb2e3a249850fb1
--- /dev/null
+++ b/dev-support/docker-images/submarine/Dockerfile
@@ -0,0 +1,48 @@
+# 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.
+
+FROM alpine:3.10
+MAINTAINER Apache Software Foundation
+
+# If you are in China, enabling the following two lines of code can speed up the build of the image, but it may cause failure in travis.
+# So when submitting the code, please make sure the following 2 lines of code are in a commented state
+# RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.10/main" > /etc/apk/repositories
+# RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.10/community" >> /etc/apk/repositories
+
+# INSTALL openjdk
+RUN apk update && \
+ apk add --no-cache openjdk8 tzdata bash tini && \
+ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
+ echo Asia/Shanghai > /etc/timezone && \
+ apk del tzdata && \
+ rm -rf /tmp/* /var/cache/apk/*
+
+ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk/jre
+
+# Install Submarine
+ADD ./tmp/submarine-dist-*.tar.gz /opt/
+RUN ln -s /opt/submarine-dist-* "/opt/submarine-current"
+ADD ./tmp/submarine-site.xml "/opt/submarine-current/conf/"
+ADD ./tmp/submarine.sh "/opt/submarine-current/bin/"
+ADD ./tmp/mysql-connector-java-5.1.39.jar "/opt/submarine-current/lib/"
+
+WORKDIR /opt/submarine-current
+
+# Submarine port
+EXPOSE 8080
+
+ENTRYPOINT ["/sbin/tini", "--"]
+
+CMD ["/bin/bash", "-c", "/opt/submarine-current/bin/submarine.sh start"]
diff --git a/dev-support/docker-images/submarine/build.sh b/dev-support/docker-images/submarine/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2fd38470b0d3def462481d84aef118de0cfe3d08
--- /dev/null
+++ b/dev-support/docker-images/submarine/build.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euxo pipefail
+
+SUBMARINE_VERSION=0.5.0
+SUBMARINE_IMAGE_NAME="apache/submarine:server-${SUBMARINE_VERSION}"
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ PWD=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ PWD=$(dirname ${BASH_SOURCE-$0})
+fi
+export CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+export SUBMARINE_HOME=${CURRENT_PATH}/../../..
+
+if [ ! -d "${SUBMARINE_HOME}/submarine-dist/target" ]; then
+ mkdir "${SUBMARINE_HOME}/submarine-dist/target"
+fi
+submarine_dist_exists=$(find -L "${SUBMARINE_HOME}/submarine-dist/target" -name "submarine-dist-${SUBMARINE_VERSION}*.tar.gz")
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_dist_exists}" ]]; then
+ cd "${SUBMARINE_HOME}"
+ mvn clean package -DskipTests
+fi
+
+mkdir -p "${CURRENT_PATH}/tmp"
+cp ${SUBMARINE_HOME}/submarine-dist/target/submarine-dist-${SUBMARINE_VERSION}*.tar.gz "${CURRENT_PATH}/tmp"
+
+# download mysql connect java
+MYSQL_VERSION=5.1.39
+MYSQL_JAR_URL="https://repo1.maven.org/maven2/mysql/mysql-connector-java/${MYSQL_VERSION}/mysql-connector-java-${MYSQL_VERSION}.jar"
+tmpfile=$(mktemp)
+trap "test -f $tmpfile && rm $tmpfile" RETURN
+curl -L -o $tmpfile ${MYSQL_JAR_URL}
+mv $tmpfile ${CURRENT_PATH}/tmp/mysql-connector-java-${MYSQL_VERSION}.jar
+
+# Replace the mysql jdbc.url in the submarine-site.xml file with the link name of the submarine container
+# `submarine-database` is submarine database container name
+cp ${SUBMARINE_HOME}/conf/submarine-site.xml "${CURRENT_PATH}/tmp/"
+sed -i.bak 's/127.0.0.1:3306/submarine-database:3306/g' "${CURRENT_PATH}/tmp/submarine-site.xml"
+
+cp ${SUBMARINE_HOME}/bin/submarine.sh "${CURRENT_PATH}/tmp/"
+
+# build image
+cd ${CURRENT_PATH}
+echo "Start building the ${SUBMARINE_IMAGE_NAME} docker image ..."
+docker build -t ${SUBMARINE_IMAGE_NAME} .
+
+# clean temp file
+rm -rf "${CURRENT_PATH}/tmp"
diff --git a/dev-support/k8s/deploy-kubeflow-operators.sh b/dev-support/k8s/deploy-kubeflow-operators.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ec12aa65a12cc07dab16604250c5f2910dec85a7
--- /dev/null
+++ b/dev-support/k8s/deploy-kubeflow-operators.sh
@@ -0,0 +1,165 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+set -euo pipefail
+
+readonly TF_OPERATOR_IMAGE="apache/submarine:tf_operator-v1.1.0-g92389064"
+readonly PYTORCH_OPERATOR_IMAGE="apache/submarine:pytorch-operator-v1.1.0-gd596e904"
+readonly TF_MNIST_IMAGE="apache/submarine:tf-mnist-with-summaries-1.0"
+readonly PT_MNIST_IMAGE="apache/submarine:pytorch-dist-mnist-1.0"
+
+if [ -L "${BASH_SOURCE-$0}" ]; then
+ PWD=$(dirname "$(readlink "${BASH_SOURCE-$0}")")
+else
+ PWD=$(dirname "${BASH_SOURCE-$0}")
+fi
+CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+export CURRENT_PATH
+export SUBMARINE_HOME=${CURRENT_PATH}/../..
+# lib.sh use the ROOT variable
+export ROOT="${SUBMARINE_HOME}/submarine-cloud/"
+export KUBECONFIG="${HOME}/.kube/kind-config-${clusterName:-kind}"
+
+# shellcheck source=./../../submarine-cloud/hack/lib.sh
+source "${SUBMARINE_HOME}/submarine-cloud/hack/lib.sh"
+
+###########################################
+# Load local docker image into registry
+# Globals:
+# KIND_BIN
+# Arguments:
+# image
+###########################################
+function load_image_to_registry() {
+ if [[ ! $(docker inspect "$1" > /dev/null) ]] ; then
+ docker pull "$1"
+ fi
+ ${KIND_BIN} load docker-image "$1"
+}
+
+###########################################
+# Deploy tf-operator on K8s
+# Globals:
+# KUBECTL_BIN
+# CURRENT_PATH
+# TF_OPERATOR_IMAGE
+# Arguments:
+# useSample
+###########################################
+function deploy_tf_operator() {
+ load_image_to_registry "${TF_OPERATOR_IMAGE}"
+
+ ${KUBECTL_BIN} apply -f "${CURRENT_PATH}/tfjob/crd.yaml"
+ ${KUBECTL_BIN} kustomize "${CURRENT_PATH}/tfjob/operator" \
+ | ${KUBECTL_BIN} apply -f -
+
+ if [[ ${1:-} == "true" ]]; then
+ load_image_to_registry "${TF_MNIST_IMAGE}"
+ fi
+}
+
+###########################################
+# Deploy tf-operator on K8s
+# Globals:
+# KUBECTL_BIN
+# CURRENT_PATH
+# PYTORCH_OPERATOR_IMAGE
+# Arguments:
+# useSample
+###########################################
+function deploy_pytorch_operator() {
+ load_image_to_registry "${PYTORCH_OPERATOR_IMAGE}"
+ ${KUBECTL_BIN} apply -f "${CURRENT_PATH}/pytorchjob"
+
+ if [[ ${1:-} == "true" ]]; then
+ load_image_to_registry "${PT_MNIST_IMAGE}"
+ fi
+}
+
+###########################################
+# Print the usage information
+###########################################
+function usage() {
+ cat </dev/null; pwd)
+export CURRENT_PATH
+export SUBMARINE_HOME=${CURRENT_PATH}/../..
+# lib.sh use the ROOT variable
+export ROOT="${SUBMARINE_HOME}/submarine-cloud/"
+export KUBECONFIG="${HOME}/.kube/kind-config-${clusterName:-kind}"
+
+# shellcheck source=./../../submarine-cloud/hack/lib.sh
+source "${SUBMARINE_HOME}/submarine-cloud/hack/lib.sh"
+
+###########################################
+# Load local docker image into registry
+# Globals:
+# KIND_BIN
+# Arguments:
+# image
+###########################################
+function load_image_to_registry() {
+ if [[ ! $(docker inspect "$1" > /dev/null) ]] ; then
+ docker pull "$1"
+ fi
+ ${KIND_BIN} load docker-image "$1"
+}
+
+
+function main() {
+
+ hack::ensure_kubectl
+
+ load_image_to_registry "${NOTEBOOK_CONTROLLER_IMAGE}"
+ ${KUBECTL_BIN} apply -k "${CURRENT_PATH}/notebook-controller"
+
+}
+
+main "$@"
diff --git a/dev-support/k8s/deploy-traefik.sh b/dev-support/k8s/deploy-traefik.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3fb84003465b1aa58cbb464c33011a8b1a33f219
--- /dev/null
+++ b/dev-support/k8s/deploy-traefik.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+set -euo pipefail
+
+readonly TRAEFIK_IMAGE="traefik:v2.2"
+
+if [ -L "${BASH_SOURCE-$0}" ]; then
+ PWD=$(dirname "$(readlink "${BASH_SOURCE-$0}")")
+else
+ PWD=$(dirname "${BASH_SOURCE-$0}")
+fi
+CURRENT_PATH=$(cd "${PWD}">/dev/null; pwd)
+export CURRENT_PATH
+export SUBMARINE_HOME=${CURRENT_PATH}/../..
+# lib.sh use the ROOT variable
+export ROOT="${SUBMARINE_HOME}/submarine-cloud/"
+export KUBECONFIG="${HOME}/.kube/kind-config-${clusterName:-kind}"
+
+# shellcheck source=./../../submarine-cloud/hack/lib.sh
+source "${SUBMARINE_HOME}/submarine-cloud/hack/lib.sh"
+
+###########################################
+# Load local docker image into registry
+# Globals:
+# KIND_BIN
+# Arguments:
+# image
+###########################################
+function load_image_to_registry() {
+ if [[ ! $(docker inspect "$1" > /dev/null) ]] ; then
+ docker pull "$1"
+ fi
+ ${KIND_BIN} load docker-image "$1"
+}
+
+function main() {
+ hack::ensure_kubectl
+ echo "Setting up ingress on a kind cluster."
+ load_image_to_registry "${TRAEFIK_IMAGE}"
+ ${KUBECTL_BIN} apply -k "${CURRENT_PATH}/traefik"
+}
+
+main "@"
diff --git a/dev-support/k8s/notebook-controller/cluster-role-binding.yaml b/dev-support/k8s/notebook-controller/cluster-role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a1a394540145b946de5afb10e71c63c65d4c77a4
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/cluster-role-binding.yaml
@@ -0,0 +1,11 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: role-binding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: role
+subjects:
+- kind: ServiceAccount
+ name: service-account
diff --git a/dev-support/k8s/notebook-controller/cluster-role.yaml b/dev-support/k8s/notebook-controller/cluster-role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..16b6253a8f6b3b5bc551950501c5ebe555a5ccd1
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/cluster-role.yaml
@@ -0,0 +1,107 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: role
+rules:
+- apiGroups:
+ - apps
+ resources:
+ - statefulsets
+ - deployments
+ verbs:
+ - '*'
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - services
+ verbs:
+ - '*'
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+- apiGroups:
+ - kubeflow.org
+ resources:
+ - notebooks
+ - notebooks/status
+ - notebooks/finalizers
+ verbs:
+ - '*'
+- apiGroups:
+ - networking.istio.io
+ resources:
+ - virtualservices
+ verbs:
+ - '*'
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-notebooks-admin
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-notebooks-admin: "true"
+rules: []
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-notebooks-edit
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true"
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-notebooks-admin: "true"
+rules:
+- apiGroups:
+ - kubeflow.org
+ resources:
+ - notebooks
+ - notebooks/status
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - delete
+ - deletecollection
+ - patch
+ - update
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-notebooks-view
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true"
+rules:
+- apiGroups:
+ - kubeflow.org
+ resources:
+ - notebooks
+ - notebooks/status
+ verbs:
+ - get
+ - list
+ - watch
diff --git a/dev-support/k8s/notebook-controller/crd.yaml b/dev-support/k8s/notebook-controller/crd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b6556bd4ccbe0c3afb189264d4402c2ac00861f6
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/crd.yaml
@@ -0,0 +1,64 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: notebooks.kubeflow.org
+spec:
+ group: kubeflow.org
+ names:
+ kind: Notebook
+ plural: notebooks
+ singular: notebook
+ scope: Namespaced
+ subresources:
+ status: {}
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: false
+ - name: v1beta1
+ served: true
+ storage: true
+ - name: v1
+ served: true
+ storage: false
+ validation:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ template:
+ description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ Important: Run "make" to regenerate code after modifying this file'
+ properties:
+ spec:
+ type: object
+ type: object
+ type: object
+ status:
+ properties:
+ conditions:
+ description: Conditions is an array of current conditions
+ items:
+ properties:
+ type:
+ description: Type of the confition/
+ type: string
+ required:
+ - type
+ type: object
+ type: array
+ required:
+ - conditions
+ type: object
diff --git a/dev-support/k8s/notebook-controller/deployment.yaml b/dev-support/k8s/notebook-controller/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cb7c93c641353d3763f751b67f3003d57866667f
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/deployment.yaml
@@ -0,0 +1,23 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: deployment
+spec:
+ template:
+ metadata:
+ annotations:
+ sidecar.istio.io/inject: "false"
+ spec:
+ containers:
+ - name: manager
+ image: apache/submarine:notebook-controller-v1.1.0-g253890cb
+ command:
+ - /manager
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ httpGet:
+ path: /metrics
+ port: 8080
+ initialDelaySeconds: 30
+ periodSeconds: 30
+ serviceAccountName: service-account
diff --git a/dev-support/k8s/notebook-controller/deployment_patch.yaml b/dev-support/k8s/notebook-controller/deployment_patch.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a7dfb43349b91b8150eefe5b90be904fb5938fe7
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/deployment_patch.yaml
@@ -0,0 +1,15 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: deployment
+spec:
+ template:
+ spec:
+ containers:
+ - name: manager
+ env:
+ # We use a patch to set the USE_ISTIO because in other patches
+ # we want to set it to a configMapRef and so if we include the value
+ # in the base when we do the merge we end up with 2 fields setting the value.
+ - name: USE_ISTIO
+ value: "false"
\ No newline at end of file
diff --git a/dev-support/k8s/notebook-controller/kustomization.yaml b/dev-support/k8s/notebook-controller/kustomization.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f0c75d5827d92896c845aa7684095240e1eae1b2
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/kustomization.yaml
@@ -0,0 +1,42 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- cluster-role-binding.yaml
+- cluster-role.yaml
+- crd.yaml
+- deployment.yaml
+- service-account.yaml
+- service.yaml
+namePrefix: notebook-controller-
+namespace: default
+patchesStrategicMerge:
+- deployment_patch.yaml
+commonLabels:
+ app: notebook-controller
+ kustomize.component: notebook-controller
+images:
+- name: apache/submarine
+ newName: apache/submarine
+ newTag: notebook-controller-v1.1.0-g253890cb
+configMapGenerator:
+- name: parameters
+ literals:
+ - USE_ISTIO=false
+ - ISTIO_GATEWAY=
+generatorOptions:
+ disableNameSuffixHash: true
+vars:
+- fieldref:
+ fieldPath: data.USE_ISTIO
+ name: USE_ISTIO
+ objref:
+ apiVersion: v1
+ kind: ConfigMap
+ name: parameters
+- fieldref:
+ fieldPath: data.ISTIO_GATEWAY
+ name: ISTIO_GATEWAY
+ objref:
+ apiVersion: v1
+ kind: ConfigMap
+ name: parameters
diff --git a/dev-support/k8s/notebook-controller/service-account.yaml b/dev-support/k8s/notebook-controller/service-account.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a36cbd800f609a441b72e0f38db6a5cdeea4a91f
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/service-account.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: service-account
diff --git a/dev-support/k8s/notebook-controller/service.yaml b/dev-support/k8s/notebook-controller/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c7368f970344b6b76d7acaa9af79f36d8d1fadea
--- /dev/null
+++ b/dev-support/k8s/notebook-controller/service.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: service
+spec:
+ ports:
+ - port: 443
diff --git a/dev-support/k8s/pytorchjob/crd.yaml b/dev-support/k8s/pytorchjob/crd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4a8cf899d92b240de5adfdb5967d4534bb3bb682
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/crd.yaml
@@ -0,0 +1,42 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: pytorchjobs.kubeflow.org
+spec:
+ additionalPrinterColumns:
+ - JSONPath: .status.conditions[-1:].type
+ name: State
+ type: string
+ - JSONPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ group: kubeflow.org
+ names:
+ kind: PyTorchJob
+ plural: pytorchjobs
+ singular: pytorchjob
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ properties:
+ spec:
+ properties:
+ pytorchReplicaSpecs:
+ properties:
+ Master:
+ properties:
+ replicas:
+ maximum: 1
+ minimum: 1
+ type: integer
+ Worker:
+ properties:
+ replicas:
+ minimum: 1
+ type: integer
+ versions:
+ - name: v1
+ served: true
+ storage: true
diff --git a/dev-support/k8s/pytorchjob/deploy-pytorch-operator.sh b/dev-support/k8s/pytorchjob/deploy-pytorch-operator.sh
new file mode 100755
index 0000000000000000000000000000000000000000..07f7b075faa52411e24542944d3eb4f3eb2c3ebf
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/deploy-pytorch-operator.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# description: Start and stop daemon script for.
+#
+
+kubectl apply -f ./namespace.yaml
+sleep 5
+# there're two deployment yaml file. One for K8s version prior to 1.16. One for 1.16+ due to API incompatibility
+kubectl apply -f ./
diff --git a/dev-support/k8s/pytorchjob/deployment.yaml b/dev-support/k8s/pytorchjob/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6ebcea736e2540917059bcdae2ad1e3f009af72f
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/deployment.yaml
@@ -0,0 +1,34 @@
+apiVersion: extensions/v1beta1
+#apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: pytorch-operator
+ namespace: default
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ name: pytorch-operator
+ template:
+ metadata:
+ labels:
+ name: pytorch-operator
+ spec:
+ containers:
+ - command:
+ - /pytorch-operator.v1
+ - --alsologtostderr
+ - -v=1
+ - --monitoring-port=8443
+ env:
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: MY_POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ image: apache/submarine:pytorch-operator-v1.1.0-gd596e904
+ name: pytorch-operator
+ serviceAccountName: pytorch-operator
diff --git a/dev-support/k8s/pytorchjob/deployment_v1.16plus.yaml b/dev-support/k8s/pytorchjob/deployment_v1.16plus.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5db665bd5fe8ff6aae46294e65f295a0473072e1
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/deployment_v1.16plus.yaml
@@ -0,0 +1,57 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ labels:
+ name: pytorch-operator
+ name: pytorch-operator
+ namespace: default
+spec:
+ progressDeadlineSeconds: 2147483647
+ replicas: 1
+ revisionHistoryLimit: 2147483647
+ selector:
+ matchLabels:
+ name: pytorch-operator
+ strategy:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 1
+ type: RollingUpdate
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ name: pytorch-operator
+ spec:
+ containers:
+ - command:
+ - /pytorch-operator.v1
+ - --alsologtostderr
+ - -v=1
+ - --monitoring-port=8443
+ env:
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.namespace
+ - name: MY_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ image: apache/submarine:pytorch-operator-v1.1.0-gd596e904
+ imagePullPolicy: IfNotPresent
+ name: pytorch-operator
+ resources: {}
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ securityContext: {}
+ serviceAccount: pytorch-operator
+ serviceAccountName: pytorch-operator
+ terminationGracePeriodSeconds: 30
+status: {}
diff --git a/dev-support/k8s/pytorchjob/namespace.yaml b/dev-support/k8s/pytorchjob/namespace.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..559fbc3276c8b8d8767b7cfc243f83d22a79ef5f
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/namespace.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: submarine
diff --git a/dev-support/k8s/pytorchjob/podgroup.yaml b/dev-support/k8s/pytorchjob/podgroup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1432fc160f238e8b90aa6e7cb3fdc4f29f2b1bb4
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/podgroup.yaml
@@ -0,0 +1,39 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: podgroups.scheduling.incubator.k8s.io
+spec:
+ group: scheduling.incubator.k8s.io
+ names:
+ kind: PodGroup
+ plural: podgroups
+ scope: Namespaced
+ validation:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ type: string
+ kind:
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ minMember:
+ format: int32
+ type: integer
+ type: object
+ status:
+ properties:
+ succeeded:
+ format: int32
+ type: integer
+ failed:
+ format: int32
+ type: integer
+ running:
+ format: int32
+ type: integer
+ type: object
+ type: object
+ version: v1alpha1
diff --git a/dev-support/k8s/pytorchjob/rbac.yaml b/dev-support/k8s/pytorchjob/rbac.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0261c8501c37c9fe20309ad30e69336efbdd7ecb
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/rbac.yaml
@@ -0,0 +1,53 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app: pytorch-operator
+ name: pytorch-operator
+ namespace: default
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+ labels:
+ app: pytorch-operator
+ name: pytorch-operator
+rules:
+- apiGroups:
+ - kubeflow.org
+ resources:
+ - pytorchjobs
+ - pytorchjobs/status
+ verbs:
+ - '*'
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - '*'
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ - endpoints
+ - events
+ verbs:
+ - '*'
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app: pytorch-operator
+ name: pytorch-operator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: pytorch-operator
+subjects:
+- kind: ServiceAccount
+ name: pytorch-operator
+ namespace: default
+---
diff --git a/dev-support/k8s/pytorchjob/service.yaml b/dev-support/k8s/pytorchjob/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8e57a496ff80f8c538321b04e2c37f072217cb4b
--- /dev/null
+++ b/dev-support/k8s/pytorchjob/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/port: "8443"
+ prometheus.io/scrape: "true"
+ labels:
+ app: pytorch-operator
+ name: pytorch-operator
+ namespace: default
+spec:
+ ports:
+ - name: monitoring-port
+ port: 8443
+ targetPort: 8443
+ selector:
+ name: pytorch-operator
+ type: ClusterIP
diff --git a/dev-support/k8s/tfjob/crd.yaml b/dev-support/k8s/tfjob/crd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..38f850bd7b1dbb604a7edee87ba16cc2584a359e
--- /dev/null
+++ b/dev-support/k8s/tfjob/crd.yaml
@@ -0,0 +1,42 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: tfjobs.kubeflow.org
+spec:
+ group: kubeflow.org
+ scope: Namespaced
+ names:
+ kind: TFJob
+ singular: tfjob
+ plural: tfjobs
+ versions:
+ - name: v1
+ served: true
+ storage: true
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ properties:
+ spec:
+ properties:
+ tfReplicaSpecs:
+ properties:
+ # The validation works when the configuration contains
+ # `Worker`, `PS` or `Chief`. Otherwise it will not be validated.
+ Worker:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ PS:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ Chief:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ maximum: 1
diff --git a/dev-support/k8s/tfjob/operator/cluster-role-binding.yaml b/dev-support/k8s/tfjob/operator/cluster-role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e05aad7fc47a63b548e534f1a6efc1c4eb56474f
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/cluster-role-binding.yaml
@@ -0,0 +1,14 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app: tf-job-operator
+ name: tf-job-operator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: tf-job-operator
+subjects:
+- kind: ServiceAccount
+ name: tf-job-operator
diff --git a/dev-support/k8s/tfjob/operator/cluster-role.yaml b/dev-support/k8s/tfjob/operator/cluster-role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2740b98e0b27e2e5168393d966abebcaf372803d
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/cluster-role.yaml
@@ -0,0 +1,96 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+ labels:
+ app: tf-job-operator
+ name: tf-job-operator
+rules:
+ - apiGroups:
+ - kubeflow.org
+ resources:
+ - tfjobs
+ - tfjobs/status
+ - tfjobs/finalizers
+ verbs:
+ - '*'
+ - apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - '*'
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ - endpoints
+ - events
+ verbs:
+ - '*'
+ - apiGroups:
+ - apps
+ - extensions
+ resources:
+ - deployments
+ verbs:
+ - '*'
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-tfjobs-admin
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-tfjobs-admin: "true"
+rules: []
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-tfjobs-edit
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true"
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-tfjobs-admin: "true"
+rules:
+ - apiGroups:
+ - kubeflow.org
+ resources:
+ - tfjobs
+ - tfjobs/status
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - delete
+ - deletecollection
+ - patch
+ - update
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: kubeflow-tfjobs-view
+ labels:
+ rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true"
+rules:
+ - apiGroups:
+ - kubeflow.org
+ resources:
+ - tfjobs
+ - tfjobs/status
+ verbs:
+ - get
+ - list
+ - watch
diff --git a/dev-support/k8s/tfjob/operator/deployment.yaml b/dev-support/k8s/tfjob/operator/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b4115b9100dbd33ca5316a85fa85b44d14569e5e
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/deployment.yaml
@@ -0,0 +1,31 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: tf-job-operator
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ name: tf-job-operator
+ annotations:
+ sidecar.istio.io/inject: "false"
+ spec:
+ containers:
+ - args:
+ - --alsologtostderr
+ - -v=1
+ - --monitoring-port=8443
+ env:
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: MY_POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ image: apache/submarine:tf_operator-v1.1.0-g92389064
+ name: tf-job-operator
+ serviceAccountName: tf-job-operator
diff --git a/dev-support/k8s/tfjob/operator/kustomization.yaml b/dev-support/k8s/tfjob/operator/kustomization.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..06f3f6ee064fcd6233df3d9022e44f467d578b84
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/kustomization.yaml
@@ -0,0 +1,15 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: default
+resources:
+- cluster-role-binding.yaml
+- cluster-role.yaml
+- deployment.yaml
+- service-account.yaml
+- service.yaml
+commonLabels:
+ kustomize.component: tf-job-operator
+images:
+- name: apache/submarine
+ newName: apache/submarine
+ newTag: tf_operator-v1.1.0-g92389064
diff --git a/dev-support/k8s/tfjob/operator/service-account.yaml b/dev-support/k8s/tfjob/operator/service-account.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c7be4e33e68795aa298db796091eb0fbbcfb36b6
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/service-account.yaml
@@ -0,0 +1,14 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app: tf-job-dashboard
+ name: tf-job-dashboard
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app: tf-job-operator
+ name: tf-job-operator
diff --git a/dev-support/k8s/tfjob/operator/service.yaml b/dev-support/k8s/tfjob/operator/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..97f92e3ea185b7e19922f3812f56e02b995e7847
--- /dev/null
+++ b/dev-support/k8s/tfjob/operator/service.yaml
@@ -0,0 +1,19 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+ annotations:
+ prometheus.io/path: /metrics
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "8443"
+ labels:
+ app: tf-job-operator
+ name: tf-job-operator
+spec:
+ ports:
+ - name: monitoring-port
+ port: 8443
+ targetPort: 8443
+ selector:
+ name: tf-job-operator
+ type: ClusterIP
diff --git a/dev-support/k8s/traefik/cluster-role-binding.yaml b/dev-support/k8s/traefik/cluster-role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe862602be23e58ebc9581ad450d9e3ee7d1ab31
--- /dev/null
+++ b/dev-support/k8s/traefik/cluster-role-binding.yaml
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: traefik-ingress-controller
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: traefik-ingress-controller
+subjects:
+- kind: ServiceAccount
+ name: traefik-ingress-controller
+ namespace: default
diff --git a/dev-support/k8s/traefik/cluster-role.yaml b/dev-support/k8s/traefik/cluster-role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74537deaa091c08972073aa415a8176de18dcee6
--- /dev/null
+++ b/dev-support/k8s/traefik/cluster-role.yaml
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: traefik-ingress-controller
+
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - services
+ - endpoints
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - extensions
+ resources:
+ - ingresses
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - extensions
+ resources:
+ - ingresses/status
+ verbs:
+ - update
+- apiGroups:
+ - traefik.containo.us
+ resources:
+ - middlewares
+ - ingressroutes
+ - traefikservices
+ - ingressroutetcps
+ - ingressrouteudps
+ - tlsoptions
+ - tlsstores
+ verbs:
+ - get
+ - list
+ - watch
diff --git a/dev-support/k8s/traefik/crd.yaml b/dev-support/k8s/traefik/crd.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..76776bdec11e8312955463bfd8d1b6e00ea40325
--- /dev/null
+++ b/dev-support/k8s/traefik/crd.yaml
@@ -0,0 +1,120 @@
+#
+# 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.
+#
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ingressroutes.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: IngressRoute
+ plural: ingressroutes
+ singular: ingressroute
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: middlewares.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: Middleware
+ plural: middlewares
+ singular: middleware
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ingressroutetcps.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: IngressRouteTCP
+ plural: ingressroutetcps
+ singular: ingressroutetcp
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ingressrouteudps.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: IngressRouteUDP
+ plural: ingressrouteudps
+ singular: ingressrouteudp
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: tlsoptions.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: TLSOption
+ plural: tlsoptions
+ singular: tlsoption
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: tlsstores.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: TLSStore
+ plural: tlsstores
+ singular: tlsstore
+ scope: Namespaced
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: traefikservices.traefik.containo.us
+
+spec:
+ group: traefik.containo.us
+ version: v1alpha1
+ names:
+ kind: TraefikService
+ plural: traefikservices
+ singular: traefikservice
+ scope: Namespaced
diff --git a/dev-support/k8s/traefik/deployment.yaml b/dev-support/k8s/traefik/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..be670cba1bfb3c3c9af90b4bbf1973c917572cb0
--- /dev/null
+++ b/dev-support/k8s/traefik/deployment.yaml
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+ namespace: default
+ name: traefik
+ labels:
+ app: traefik
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: traefik
+ template:
+ metadata:
+ labels:
+ app: traefik
+ spec:
+ serviceAccountName: traefik-ingress-controller
+ containers:
+ - name: traefik
+ image: traefik:v2.2
+ args:
+ - --accesslog
+ - --entrypoints.web.Address=:80
+ - --entrypoints.websecure.Address=:443
+ - --ping=true
+ - --providers.kubernetescrd
+ - --providers.kubernetesingress
+ ports:
+ - name: web
+ containerPort: 80
+ - name: websecure
+ containerPort: 443
diff --git a/dev-support/k8s/traefik/kustomization.yaml b/dev-support/k8s/traefik/kustomization.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e7f05d060e2cdf8dd3a634d520936ea5e683ac94
--- /dev/null
+++ b/dev-support/k8s/traefik/kustomization.yaml
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- cluster-role.yaml
+- cluster-role-binding.yaml
+- crd.yaml
+- deployment.yaml
+- service-account.yaml
+- service.yaml
+namespace: default
+commonLabels:
+ kustomize.component: traefik
+
+images:
+- name: traefik
+ newName: traefik
+ newTag: v2.2
diff --git a/dev-support/k8s/traefik/service-account.yaml b/dev-support/k8s/traefik/service-account.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fee03de6233593e7ad87de92e2a2ba815f34f6b2
--- /dev/null
+++ b/dev-support/k8s/traefik/service-account.yaml
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: traefik-ingress-controller
diff --git a/dev-support/k8s/traefik/service.yaml b/dev-support/k8s/traefik/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d00005ae433433b90670ee0cea76a2ece995ff33
--- /dev/null
+++ b/dev-support/k8s/traefik/service.yaml
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: traefik
+spec:
+ type: NodePort
+ ports:
+ - protocol: TCP
+ name: web
+ port: 80
+ nodePort: 32080
+ - protocol: TCP
+ name: websecure
+ port: 443
+ nodePort: 32443
+ selector:
+ app: traefik
diff --git a/dev-support/maven-config/checkstyle.xml b/dev-support/maven-config/checkstyle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e31aabf00c6fb44a1979c36b94f39e6fdedef54e
--- /dev/null
+++ b/dev-support/maven-config/checkstyle.xml
@@ -0,0 +1,289 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev-support/maven-config/scalastyle-config.xml b/dev-support/maven-config/scalastyle-config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0deecf9cfd7bd6e23074ec8b9f5b3a760f00bd8a
--- /dev/null
+++ b/dev-support/maven-config/scalastyle-config.xml
@@ -0,0 +1,288 @@
+
+
+
+ Scalastyle standard configuration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ARROW, EQUALS, ELSE, TRY, CATCH, FINALLY, LARROW, RARROW
+
+
+
+
+
+ ARROW, EQUALS, COMMA, COLON, IF, ELSE, DO, WHILE, FOR, MATCH, TRY, CATCH, FINALLY, LARROW, RARROW
+
+
+
+
+
+
+
+ Runtime\.getRuntime\.addShutdownHook
+
+
+
+
+ mutable\.SynchronizedBuffer
+
+
+
+
+ (\.toUpperCase|\.toLowerCase)(?!(\(|\(Locale.ROOT\)))
+
+
+
+
+ throw new \w+Error\(
+
+
+
+
+ JavaConversions
+ Instead of importing implicits in scala.collection.JavaConversions._, import
+ scala.collection.JavaConverters._ and use .asScala / .asJava methods
+
+
+
+ org\.apache\.commons\.lang\.
+ Use Commons Lang 3 classes (package org.apache.commons.lang3.*) instead
+ of Commons Lang 2 (package org.apache.commons.lang.*)
+
+
+
+ extractOpt
+ Use jsonOption(x).map(.extract[T]) instead of .extractOpt[T], as the latter
+ is slower.
+
+
+
+
+ java,scala,3rdParty,submarine
+ javax?\..*
+ scala\..*
+ (?!org\.apache\.submarine\.).*
+ org\.apache\.submarine\..*
+ false
+
+
+
+
+
+ COMMA
+
+
+
+
+ \)\{
+
+
+
+
+ (?m)^(\s*)/[*][*].*$(\r|)\n^\1 [*]
+ Use Javadoc style indentation for multiline comments
+
+
+
+ case[^\n>]*=>\s*\{
+ Omit braces in case clauses.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 800>
+
+
+
+
+ 30
+
+
+
+
+ 10
+
+
+
+
+ 50
+
+
+
+
+
+
+
+
+
+
+ -1,0,1,2,3
+
+
+
diff --git a/dev-support/mini-submarine/Dockerfile b/dev-support/mini-submarine/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..80e066b01440d00979860e2d2956f6d38ea9d7e3
--- /dev/null
+++ b/dev-support/mini-submarine/Dockerfile
@@ -0,0 +1,144 @@
+# 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.
+
+FROM ubuntu:18.04
+#INSTALL JAVA
+RUN apt-get -q update \
+ && apt-get install -y wget software-properties-common \
+ && add-apt-repository -y ppa:webupd8team/java \
+ && apt-get update \
+ && wget http://archive.ubuntu.com/ubuntu/pool/main/m/mesa/libgl1-mesa-dri_19.2.8-0ubuntu0~18.04.2_amd64.deb \
+ && wget http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu60_60.2-3ubuntu3.1_amd64.deb \
+ && apt-get install -y ./libgl1-mesa-dri_19.2.8-0ubuntu0~18.04.2_amd64.deb \
+ && apt-get install -y ./libicu60_60.2-3ubuntu3.1_amd64.deb \
+ && apt-get -q install -y --no-install-recommends openjdk-8-jdk libbcprov-java \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
+
+# INSTALL Docker
+RUN \
+ apt-get update && \
+ apt-get -y install apt-transport-https ca-certificates curl software-properties-common && \
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
+ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
+ apt-get update && \
+ apt-get -y install docker-ce
+# So no need to mount host's /var/run/docker.sock, dockerd will create in local fs
+VOLUME /var/lib/docker
+
+#INSTALL user tools
+RUN \
+ apt-get update && \
+ apt-get -y install vim
+
+# Install libgomp1 for MXNet
+RUN \
+ apt-get update && \
+ apt-get -y install libgomp1
+
+#INSTALL HADOOP
+# Add native libs
+ARG HADOOP_VERSION=
+ADD hadoop-${HADOOP_VERSION}.tar.gz /usr/local
+#ADD hadoop-native-${HADOOP_VERSION}.tar /usr/local/hadoop-${HADOOP_VERSION}/lib/native
+
+ENV HADOOP_PREFIX=/usr/local/hadoop \
+ HADOOP_COMMON_HOME=/usr/local/hadoop \
+ HADOOP_HDFS_HOME=/usr/local/hadoop \
+ HADOOP_MAPRED_HOME=/usr/local/hadoop \
+ HADOOP_YARN_HOME=/usr/local/hadoop \
+ HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop \
+ YARN_CONF_DIR=/usr/local/hadoop/etc/hadoop \
+ PATH=${PATH}:/usr/local/hadoop/bin
+
+RUN \
+ cd /usr/local && mv ./hadoop-${HADOOP_VERSION} hadoop && \
+ rm -f ${HADOOP_PREFIX}/logs/*
+
+ARG ZK_VERSION=3.4.14
+ADD zookeeper-${ZK_VERSION}.tar.gz /usr/local
+RUN mv /usr/local/zookeeper-${ZK_VERSION} /usr/local/zookeeper
+RUN sed "s#/tmp/zookeeper#/tmp/staging/zookeeper#" /usr/local/zookeeper/conf/zoo_sample.cfg > /usr/local/zookeeper/conf/zoo.cfg
+
+WORKDIR $HADOOP_PREFIX
+
+# Hdfs ports
+EXPOSE 50010 50020 50070 50075 50090 8020 9000
+# Mapred ports
+EXPOSE 19888
+#Yarn ports
+EXPOSE 8030 8031 8032 8033 8040 8042 8088
+# ZK ports
+EXPOSE 2181 2888 3888
+#Other ports
+EXPOSE 49707 2122
+# Workbench port
+EXPOSE 8080
+
+#Add spark dynamic allocation jar
+#ADD spark-2.4.0-yarn-shuffle.jar /usr/local/hadoop/share/hadoop/yarn/spark-2.4.0-yarn-shuffle.jar
+
+# Create users
+RUN \
+ groupadd -g 1007 hadoop && \
+ useradd -m -G hadoop -u 1008 -s /bin/bash yarn && \
+ chown -R root:hadoop /usr/local/hadoop && \
+ chown -R yarn:hadoop /usr/local/zookeeper
+
+# Copy Config
+COPY conf /tmp/hadoop-config
+
+ENV HADOOP_VER=${HADOOP_VERSION}
+
+#Install Spark
+ARG SPARK_VERSION=
+ENV SPARK_VER=${SPARK_VERSION}
+ADD spark-${SPARK_VERSION}-bin-hadoop2.7.tgz /opt
+ADD spark-defaults-dynamic-allocation.conf /opt/spark-${SPARK_VERSION}/conf/spark-defaults.conf
+RUN apt-get update && apt-get install -y vim python python-numpy wget zip python3 python3-distutils
+
+# Add pyspark sample
+ADD spark-script /home/yarn/spark-script
+RUN chown -R yarn /home/yarn/spark-script && \
+ chmod +x -R /home/yarn/spark-script
+
+# Add distributedShell example
+ADD conf/yarn-ds-docker.sh /home/yarn
+RUN chown -R yarn /home/yarn/yarn-ds-docker.sh && \
+ chmod +x /home/yarn/yarn-ds-docker.sh
+
+# set image name env
+ARG IMAGE_NAME=
+ENV IMAGE_N=${IMAGE_NAME}
+
+# Install Submarine
+ARG SUBMARINE_VERSION=
+ENV SUBMARINE_VER=${SUBMARINE_VERSION}
+ADD submarine-dist-${SUBMARINE_VER}-hadoop*.tar.gz /opt
+ADD pysubmarine /opt/pysubmarine
+RUN ln -s /opt/submarine-dist-${SUBMARINE_VER}* /opt/submarine-current
+ADD submarine /home/yarn/submarine
+ADD database /home/yarn/database
+
+# Build virtual python env
+RUN cd /home/yarn/submarine && \
+ chmod +x /home/yarn/submarine/* && \
+ /home/yarn/submarine/build_python_virtual_env.sh
+
+# Grant read permission for submarine job
+RUN chown -R yarn /home/yarn/submarine
+RUN chown -R yarn /opt/*
diff --git a/dev-support/mini-submarine/README.md b/dev-support/mini-submarine/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..063bbee0576761d9b076cc8d71f5f5fd31ea9df8
--- /dev/null
+++ b/dev-support/mini-submarine/README.md
@@ -0,0 +1,337 @@
+
+
+# Mini-submarine
+
+This is a docker image built for submarine development and quick start test.
+
+**Please Note: don't use the image in production environment. It's only for test purpose.**
+
+## Start mini-submarine
+
+### Use the image we provide
+
+```
+docker pull apache/submarine:mini-0.5.0
+```
+
+### Create image by yourself
+
+> You may need a VPN if your network is limited
+
+1.Clone the source code of Submarine
+```
+git clone https://github.com/apache/submarine.git
+```
+
+2.Build Submarine
+```
+cd ./submarine
+mvn clean package -DskipTests
+```
+
+3.Build image of mini-submarine
+> You can download in advance of these three kind of compressed file for building :
+> zookeeper-3.4.14.tar.gz , hadoop-2.9.2.tar.gz , spark-2.4.4-bin-hadoop2.7.tgz
+> and put them into "submarine/dev-support/mini-submarine/"
+
+```
+cd submarine/dev-support/mini-submarine/
+./build_mini-submarine.sh
+```
+#### Package An Existing Release Candidates
+When doing release, the release manager might needs to package a artifact candidates in this docker image and public the image candidate for a vote.
+In this scenario, we can do this:
+
+Put submarine candidate artifacts to a folder like "~/releases/submarine-release"
+```
+$ ls $release_candidates_path
+submarine-dist-0.5.0-hadoop-2.9.tar.gz submarine-dist-0.5.0-src.tar.gz.asc
+submarine-dist-0.5.0-hadoop-2.9.tar.gz.asc submarine-dist-0.5.0-src.tar.gz.sha512
+submarine-dist-0.5.0-hadoop-2.9.tar.gz.sha512 submarine-dist-0.5.0-src.tar.gz
+```
+```
+export submarine_version=0.5.0
+export release_candidates_path=~/releases/submarine-release
+./build_mini-submarine.sh
+#docker run -it -h submarine-dev --net=bridge --privileged -P local/mini-submarine:0.5.0 /bin/bash
+docker tag local/mini-submarine:0.5.0 apache/mini-submarine:0.5.0:RC0
+docker push apache/mini-submarine:0.5.0:RC0
+```
+In the container, we can verify that the submarine jar version is the expected 0.5.0. Then we can upload this image with a "RC" tag for a vote.
+
+### Run mini-submarine image
+
+```
+docker run -it -h submarine-dev --name mini-submarine --net=bridge --privileged -P local/mini-submarine:0.5.0 /bin/bash
+
+# In the container, use root user to bootstrap hdfs and yarn
+/tmp/hadoop-config/bootstrap.sh
+
+# Two commands to check if yarn and hdfs is running as expected
+yarn node -list -showDetails
+```
+
+If you pull the image directly, please replace "local/mini-submarine:0.5.0" with "apache/submarine:mini-0.5.0".
+
+### You should see info like this:
+
+```
+Total Nodes:1
+ Node-Id Node-State Node-Http-Address Number-of-Running-Containers
+submarine-dev:35949 RUNNING submarine-dev:8042 0
+Detailed Node Information :
+ Configured Resources :
+ Allocated Resources :
+ Resource Utilization by Node : PMem:4144 MB, VMem:4189 MB, VCores:0.25308025
+ Resource Utilization by Containers : PMem:0 MB, VMem:0 MB, VCores:0.0
+ Node-Labels :
+```
+
+```
+hdfs dfs -ls /user
+```
+
+> drwxr-xr-x - yarn supergroup 0 2019-07-22 07:59 /user/yarn
+
+## Run workbench server
+
+1. Setup mysql mariadb server
+> Because mysql and mariadb use the GPL license, So there is no binary file containing mysql in the image, you need to manually execute the script to install it.
+
+```
+/tmp/hadoop-config/setup-mysql.sh
+```
+
+You can execute command `mysql -uroot` login mysql mariadb.
+
+2. Start submarine server
+```
+su yarn
+/opt/submarine-current/bin/submarine-daemon.sh start getMysqlJar
+```
+
+3. Login submarine workbench
+
+Execute the following command in your host machine, Get the access URL of the submarine workbench running in docker
+
+```shell
+echo "http://localhost:$(docker inspect --format='{{(index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort}}' mini-submarine)"
+```
+The URL returned by the command (like to: http://localhost:32819) is opened through a browser. The username and initial password of the workbench are both `admin`.
+
+## Run a submarine job
+
+### Switch to user yarn
+
+```
+su yarn
+```
+
+### Navigate to submarine example directory
+```
+cd /home/yarn/submarine/
+```
+
+### Run a mnist TF job with submarine + TonY runtime
+```
+# run TF 1 distributed training job
+./run_submarine_mnist_tony.sh
+
+# run TF 2 distributed training job
+./run_submarine_mnist_tf2_tony.sh
+```
+When run_submarine_mnist_tony.sh is executed, mnist data is download from the url, [google mnist](https://storage.googleapis.com/cvdf-datasets/mnist/), by default. If the url is unaccessible, you can use parameter "-d" to specify a customized url.
+For example, if you are in mainland China, you can use the following command
+```
+./run_submarine_mnist_tony.sh -d http://yann.lecun.com/exdb/mnist/
+```
+
+### Run a mnist TF job via submarine server
+
+Submarine server is supposed to manage jobs lifecycle. Clients can just submit
+job parameters or yaml file to submarine server instead of submitting jobs
+directly by themselves. Submarine server can handle the rest of the work.
+
+Set submarine.server.rpc.enabled to true in the file of
+/opt/submarine-current/conf/submarine-site
+```
+
+ submarine.server.rpc.enabled
+ true
+ Run jobs using rpc server.
+
+```
+Run the following command to submit a job via submarine server
+```
+./run_submarine_mnist_tony_rpc.sh
+```
+
+### Try your own submarine program
+
+Run container with your source code. You can also use "docker cp" to an existing running container
+
+1. `docker run -it -h submarine-dev --net=bridge --privileged -v pathToMyScrit.py:/home/yarn/submarine/myScript.py local/hadoop-docker:submarine /bin/bash`
+
+2. Refer to the `run_submarine_mnist_tony.sh` and modify the script to your script
+
+3. Try to run it. Since this is a single node environment, keep in mind that the workers could have conflicts with each other. For instance, the mnist_distributed.py example has a workaround to fix the conflicts when two workers are using same "data_dir" to download data set.
+
+
+## Update Submarine Version
+
+You can follow the documentation instructions to update your own modified and compiled submarine package to the submarine container.
+
+### Build Submarine
+
+```
+cd submarine-project-dir/
+mvn clean package -DskipTests
+```
+
+### Copy submarine jar to mini-submarine container
+
+```
+docker cp submarine-all/target/submarine-all--hadoop-.jar :/tmp/
+```
+
+### Modify environment variables
+
+```
+cd /home/yarn/submarine
+vi run_customized_submarine-all_mnist.sh
+
+# Need to modify environment variables based on hadoop and submarine version numbers
+SUBMARINE_VERSION=
+HADOOP_VERSION= # default 2.9
+```
+
+### Test submarine jar package in container
+
+```
+cd /home/yarn/submarine
+./run_customized_submarine-all_mnist.sh
+```
+
+## Debug Submarine
+
+When using mini-submarine, you can debug submarine client, applicationMaster and executor for trouble shooting.
+
+### Debug submarine client
+
+Run the following command to start mini-submarine.
+
+```
+docker run -it -P -h submarine-dev --net=bridge --expose=8000 --privileged local/mini-submarine: /bin/bash
+```
+
+Debug submarine client with the parameter "--debug"
+
+```
+./run_submarine_mnist_tony.sh --debug
+```
+
+Port 8000 is used in the mini-submarine.
+You need to find the debug port mapping between mini-submarine and the host on which run mini-subamrine.
+
+```
+docker port
+```
+
+For example, we can get some info like this
+
+```
+8000/tcp -> 0.0.0.0:32804
+```
+
+Then port 32804 can be used for remote debug.
+
+### Debug submarine job applicationMaster
+
+Run the following command to start mini-submarine.
+
+```
+docker run -it -P -h submarine-dev --net=bridge --expose=8001 --privileged local/mini-submarine: /bin/bash
+```
+
+Add the following configuration in the file /usr/local/hadoop/etc/hadoop/tony.xml.
+
+```
+
+ tony.task.am.jvm.opts
+ -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8001
+
+```
+
+You can use run_submarine_mnist_tony.sh to submit a job. Port 8001 is used for AM debugging in mini-submarine.
+And the debug port mapping can be obtained using the way as [Debug submarine client](#debug) shows.
+
+### Debug submarine job executor
+
+Run the following command to start mini-submarine.
+
+```
+docker run -it -P -h submarine-dev --net=bridge --expose=8002 --privileged local/mini-submarine: /bin/bash
+```
+
+Add the following configuration in the file /usr/local/hadoop/etc/hadoop/tony.xml.
+
+```
+
+ tony.task.executor.jvm.opts
+ -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8002
+
+```
+
+Port 8002 is used for executor debugging in mini-submarine.
+To avoid port confliction, you need to use only one executor, which means the parameter of
+submarine job should be like this
+
+```
+--num_workers 1 \
+--num_ps 0 \
+```
+
+You can get the debug port mapping using the way as [Debug submarine client](#debug) shows.
+
+## Run a distributedShell job with docker container
+
+You can also run a distributedShell job in mini-submarine.
+
+```
+cd && ./yarn-ds-docker.sh
+```
+
+## Run a spark job
+
+Spark jobs are supported as well.
+
+```
+cd && cd spark-script && ./run_spark.sh
+```
+
+## Question and answer
+
+1. Submarine package name error
+
+ Because the package name of submarine 0.3.0 or higher has been changed from `apache.hadoop.yarn.submarine` to `apache.submarine`, So you need to set the Runtime settings in the `/usr/local/hadoop/etc/hadoop/submarine-site.xml` file.
+
+ ```
+
+
+ submarine.runtime.class
+ org.apache.submarine.server.submitter.yarn.YarnRuntimeFactory
+
+
+ ```
diff --git a/dev-support/mini-submarine/build_mini-submarine.sh b/dev-support/mini-submarine/build_mini-submarine.sh
new file mode 100755
index 0000000000000000000000000000000000000000..43bd8ab7123e4ba5f9d58dea9c6f3cad8039d732
--- /dev/null
+++ b/dev-support/mini-submarine/build_mini-submarine.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+# 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.
+set -euo pipefail
+hadoop_v=2.9.2
+spark_v=2.3.4
+
+submarine_v=${submarine_version:-"0.5.0"}
+echo "Using submarine version: $submarine_v"
+
+image_name="local/mini-submarine:${submarine_v}"
+
+if [ -L ${BASH_SOURCE-$0} ]; then
+ PWD=$(dirname $(readlink "${BASH_SOURCE-$0}"))
+else
+ PWD=$(dirname ${BASH_SOURCE-$0})
+fi
+export MINI_PATH=$(cd "${PWD}">/dev/null; pwd)
+SUBMARINE_PROJECT_PATH=${MINI_PATH}/../..
+
+download_package() {
+ if [ -f "$1" ]; then
+ echo "Found $1"
+ else
+ echo "Start downloading the package $1 from $2"
+ if type wget >/dev/null 2>&1; then
+ wget $2/$1
+ elif type curl >/dev/null 2>&1; then
+ curl -O $2/$1
+ else
+ echo 'We need a tool to transfer data from or to a server. Such as wget/curl.'
+ echo 'Bye, bye!'
+ exit -1
+ fi
+ fi
+}
+
+is_empty_dir(){
+ return `ls -A $1|wc -w`
+}
+
+# download hadoop
+download_package "hadoop-${hadoop_v}.tar.gz" "http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-${hadoop_v}"
+# download spark
+download_package "spark-${spark_v}-bin-hadoop2.7.tgz" "http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-${spark_v}"
+# download zookeeper
+download_package "zookeeper-3.4.14.tar.gz" "http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14"
+
+
+if [ ! -d "${SUBMARINE_PROJECT_PATH}/submarine-dist/target" ]; then
+ mkdir "${SUBMARINE_PROJECT_PATH}/submarine-dist/target"
+fi
+
+submarine_dist_exists=$(find -L "${SUBMARINE_PROJECT_PATH}/submarine-dist/target" -name "submarine-dist-${submarine_v}*.tar.gz")
+
+# If exists, use the release candidate artifacts to build image
+if [[ ! -z "${release_candidates_path:-}" ]]; then
+ submarine_dist_exists=${release_candidates_path}
+ echo "Using release candidates artifacts: ${release_candidates_path}"
+ cp ${release_candidates_path}/submarine-dist-${submarine_v}-hadoop*.tar.gz ${MINI_PATH}
+fi
+
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_dist_exists}" ]]; then
+ cd "${SUBMARINE_PROJECT_PATH}"
+ mvn clean package -DskipTests
+fi
+
+cp ${SUBMARINE_PROJECT_PATH}/submarine-dist/target/submarine-dist-${submarine_v}*.tar.gz ${MINI_PATH}
+cp -r ${SUBMARINE_PROJECT_PATH}/submarine-sdk/pysubmarine ${MINI_PATH}
+cp -r ${SUBMARINE_PROJECT_PATH}/docs/database ${MINI_PATH}
+
+# build image
+echo "Start building the mini-submarine docker image..."
+cd ${MINI_PATH}
+docker build --build-arg HADOOP_VERSION=${hadoop_v} --build-arg SPARK_VERSION=${spark_v} --build-arg SUBMARINE_VERSION=${submarine_v} --build-arg IMAGE_NAME=${image_name} -t ${image_name} .
+
+# clean template file
+rm -rf ${MINI_PATH}/database
+rm -rf ${MINI_PATH}/pysubmarine
+rm -rf ${MINI_PATH}/submarine-dist-${submarine_v}*.tar.gz
diff --git a/dev-support/mini-submarine/conf/bootstrap.sh b/dev-support/mini-submarine/conf/bootstrap.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3152c6af32deada2500ed330b81a9c34ab856f87
--- /dev/null
+++ b/dev-support/mini-submarine/conf/bootstrap.sh
@@ -0,0 +1,148 @@
+#!/usr/bin/env bash
+# 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.
+
+# start dockerd
+nohup dockerd --host=unix:///var/run/docker.sock > /var/log/dockerd.log 2>&1 &
+
+: ${HADOOP_PREFIX:=/usr/local/hadoop}
+
+. $HADOOP_PREFIX/etc/hadoop/hadoop-env.sh
+
+# Directory to find config artifacts
+CONFIG_DIR="/tmp/hadoop-config"
+
+
+# Copy config files from volume mount
+
+for f in slaves core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml container-executor.cfg capacity-scheduler.xml node-resources.xml resource-types.xml; do
+ if [[ -e ${CONFIG_DIR}/$f ]]; then
+ cp ${CONFIG_DIR}/$f $HADOOP_PREFIX/etc/hadoop/$f
+ else
+ echo "ERROR: Could not find $f in $CONFIG_DIR"
+ exit 1
+ fi
+done
+
+# Copy submarine config
+for f in slaves submarine-site.xml submarine-env.sh; do
+ if [[ -e ${CONFIG_DIR}/$f ]]; then
+ cp ${CONFIG_DIR}/$f /opt/submarine-current/conf/$f
+ else
+ echo "ERROR: Could not find $f in $CONFIG_DIR"
+ exit 1
+ fi
+done
+
+# create cgroups
+mkdir -p /sys/fs/cgroup/cpu/hadoop-yarn
+chown -R yarn /sys/fs/cgroup/cpu/hadoop-yarn
+mkdir -p /sys/fs/cgroup/memory/hadoop-yarn
+chown -R yarn /sys/fs/cgroup/memory/hadoop-yarn
+mkdir -p /sys/fs/cgroup/blkio/hadoop-yarn
+chown -R yarn /sys/fs/cgroup/blkio/hadoop-yarn
+mkdir -p /sys/fs/cgroup/net_cls/hadoop-yarn
+chown -R yarn /sys/fs/cgroup/net_cls/hadoop-yarn
+mkdir -p /sys/fs/cgroup/devices/hadoop-yarn
+chown -R yarn /sys/fs/cgroup/devices/hadoop-yarn
+
+# set container-executor permission
+chmod 6050 /usr/local/hadoop/bin/container-executor
+chmod 0400 /usr/local/hadoop/etc/hadoop/container-executor.cfg
+
+# creat log and app dir
+mkdir ${HADOOP_PREFIX}/logs
+chown yarn:hadoop ${HADOOP_PREFIX}/logs
+mkdir /var/lib/hadoop-yarn
+chown yarn:hadoop /var/lib/hadoop-yarn
+mkdir /var/log/hadoop-yarn
+chown yarn:hadoop /var/log/hadoop-yarn
+# installing libraries if any - (resource urls added comma separated to the ACP system variable)
+cd $HADOOP_PREFIX/share/hadoop/common ; for cp in ${ACP//,/ }; do echo == $cp; curl -LO $cp ; done; cd -
+
+if [[ "${HOSTNAME}" =~ "submarine-dev" ]]; then
+ mkdir -p /root/hdfs/namenode
+ $HADOOP_PREFIX/bin/hdfs namenode -format -force -nonInteractive
+ sed -i s/hdfs-nn/0.0.0.0/ /usr/local/hadoop/etc/hadoop/core-site.xml
+ nohup $HADOOP_PREFIX/sbin/hadoop-daemon.sh start namenode > /tmp/nn.log 2>&1 &
+fi
+
+if [[ "${HOSTNAME}" =~ "submarine-dev" ]]; then
+ mkdir -p /root/hdfs/datanode
+ # wait up to 30 seconds for namenode
+ # count=0 && while [[ $count -lt 15 && -z `curl -sf http://submarine-dev:50070` ]]; do echo "Waiting for hdfs-nn" ; ((count=count+1)) ; sleep 2; done
+ #[[ $count -eq 15 ]] && echo "Timeout waiting for hdfs-nn, exiting." && exit 1
+ sleep 5
+ nohup $HADOOP_PREFIX/sbin/hadoop-daemon.sh start datanode > /tmp/dn.log 2>&1 &
+fi
+
+#add yarn to hdfs user group, create hdfs folder and export hadoop path
+groupadd supergroup
+usermod -aG supergroup yarn
+usermod -aG docker yarn
+su yarn -c "/usr/local/hadoop/bin/hadoop fs -mkdir -p /user/yarn"
+echo "export PATH=$PATH:/usr/local/hadoop/bin" >> /home/yarn/.bashrc
+
+if [[ "${HOSTNAME}" =~ "submarine-dev" ]]; then
+ sed -i s/yarn-rm/0.0.0.0/ $HADOOP_PREFIX/etc/hadoop/yarn-site.xml
+
+ # start zk
+ su yarn -c "cd /usr/local/zookeeper && /usr/local/zookeeper/bin/zkServer.sh start >/dev/null 2>&1"
+
+ cp ${CONFIG_DIR}/start-yarn-rm.sh $HADOOP_PREFIX/sbin/
+ cd $HADOOP_PREFIX/sbin
+ chmod +x start-yarn-rm.sh
+ su yarn -c "/usr/local/hadoop/sbin/start-yarn-rm.sh"
+fi
+
+if [[ "${HOSTNAME}" =~ "submarine-dev" ]]; then
+ sed -i '/<\/configuration>/d' $HADOOP_PREFIX/etc/hadoop/yarn-site.xml
+ cat >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml <<- EOM
+
+ yarn.nodemanager.resource.memory-mb
+ 8192
+
+
+
+ yarn.nodemanager.resource.cpu-vcores
+ 16
+
+EOM
+ echo '' >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml
+ cp ${CONFIG_DIR}/start-yarn-nm.sh $HADOOP_PREFIX/sbin/
+ cd $HADOOP_PREFIX/sbin
+ chmod +x start-yarn-nm.sh
+
+ #copy the distributed shell script for debug purpose
+ cp ${CONFIG_DIR}/yarn-ds-docker.sh /home/yarn/
+ chown yarn /home/yarn/yarn-ds-docker.sh
+ chmod +x /home/yarn/yarn-ds-docker.sh
+
+ # wait up to 30 seconds for resourcemanager
+ count=0 && while [[ $count -lt 30 && -z `curl -sf http://submarine-dev:8088/ws/v1/cluster/info` ]]; do echo "Waiting for yarn-rm" ; ((count=count+1)) ; sleep 1; done
+ [[ $count -eq 30 ]] && echo "Timeout waiting for yarn-rm, exiting." && exit 1
+
+ su yarn -c "/usr/local/hadoop/sbin/start-yarn-nm.sh"
+fi
+
+if [[ $1 == "-d" ]]; then
+ until find ${HADOOP_PREFIX}/logs -mmin -1 | egrep -q '.*'; echo "`date`: Waiting for logs..." ; do sleep 2 ; done
+ tail -F ${HADOOP_PREFIX}/logs/* &
+ while true; do sleep 1000; done
+fi
+
+if [[ $1 == "-bash" ]]; then
+ /bin/bash
+fi
diff --git a/dev-support/mini-submarine/conf/capacity-scheduler.xml b/dev-support/mini-submarine/conf/capacity-scheduler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cc5ccb128f73af4a29b8b4a5c10550480e75da99
--- /dev/null
+++ b/dev-support/mini-submarine/conf/capacity-scheduler.xml
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+ yarn.scheduler.capacity.root.queues
+ default
+
+
+ yarn.scheduler.capacity.root.default.capacity
+ 100
+
+
+ yarn.scheduler.capacity.maximum-am-resource-percent
+ 1
+
+
+ yarn.scheduler.capacity.per-node-heartbeat.maximum-container-assignments
+ 100
+
+
+
+ yarn.scheduler.capacity.per-node-heartbeat.maximum-offswitch-assignments
+ 100
+
+
+
+
+ yarn.scheduler.capacity.resource-calculator
+ org.apache.hadoop.yarn.util.resource.DominantResourceCalculator
+
+
+
+ yarn.scheduler.capacity.multi-node-placement-enabled
+ true
+
+
+
+ yarn.scheduler.capacity.multi-node-sorting.policy.names
+ resource-based
+
+
+
+ yarn.scheduler.capacity.multi-node-sorting.policy
+ resource-based
+
+
+
+ yarn.scheduler.capacity.multi-node-sorting.policy.resource-based.class
+ org.apache.hadoop.yarn.server.resourcemanager.scheduler.placement.ResourceUsageMultiNodeLookupPolicy
+
+
diff --git a/dev-support/mini-submarine/conf/container-executor.cfg b/dev-support/mini-submarine/conf/container-executor.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..4feaeca493eca5a4fbe195e69836385a42d02613
--- /dev/null
+++ b/dev-support/mini-submarine/conf/container-executor.cfg
@@ -0,0 +1,51 @@
+# 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.
+
+yarn.nodemanager.linux-container-executor.group=hadoop
+banned.users=test
+min.user.id=1000
+#allowed.system.users=##comma separated list of system users who CAN run applications
+feature.tc.enabled=false
+
+# The configs below deal with settings for Docker
+[docker]
+ module.enabled=true
+ docker.binary=/usr/bin/docker
+# docker.allowed.devices=## comma separated list of devices that can be mounted into a container
+ docker.privileged-containers.enabled=false
+# docker.allowed.volume-drivers=## comma seperated list of allowed volume-drivers
+# docker.no-new-privileges.enabled=## enable/disable the no-new-privileges flag for docker run. Set to "true" to enable, disabled by default
+ docker.allowed.capabilities=SYS_CHROOT,MKNOD,SETFCAP,SETPCAP,FSETID,CHOWN,AUDIT_WRITE,SETGID,NET_RAW,FOWNER,SETUID,DAC_OVERRIDE,KILL,NET_BIND_SERVICE
+ docker.allowed.networks=bridge,host,none
+ docker.trusted.registries=tangzhankun,library
+ docker.allowed.ro-mounts=/sys/fs/cgroup,/etc/passwd,/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/filecache,/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/yarn/filecache,/etc/passwd
+ docker.allowed.rw-mounts=/var/log/hadoop-yarn/containers,/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/yarn,/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/filecache
+ docker.allowed.runtimes=runc,nvidia
+ docker.allowed.devices=/dev/nvidiactl,/dev/nvidia-uvm,/dev/nvidia-uvm-tools,/dev/nvidia0,/dev/nvidia-modeset
+# docker.allowed.rw-mounts=/opt/code/hadoop/hadoop-dist/target/hadoop-3.3.0-SNAPSHOT/logs,/tmp/hadoop-yarn/nm-local-dir,/home/yarn/apache-hadoop-install-dir/logs/yarn/userlogs
+
+# The configs below deal with settings for FPGA resource
+#[fpga]
+# module.enabled=## Enable/Disable the FPGA resource handler module. set to "true" to enable, disabled by default
+# fpga.major-device-number=## Major device number of FPGA, by default is 246. Strongly recommend setting this
+# fpga.allowed-device-minor-numbers=## Comma separated allowed minor device numbers, empty means all FPGA devices managed by
+[cgroups]
+ root=/sys/fs/cgroup
+ yarn-hierarchy=hadoop-yarn
+#[gpu]
+# module.enabled=true
+#[devices]
+# module.enabled=true
+# devices.allowed-numbers=8:32,8:48
diff --git a/dev-support/mini-submarine/conf/core-site.xml b/dev-support/mini-submarine/conf/core-site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1af90a714f151cae28fb87ed8f7b4cc154ec3dc7
--- /dev/null
+++ b/dev-support/mini-submarine/conf/core-site.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ fs.defaultFS
+ hdfs://hdfs-nn:9000/
+ NameNode URI
+
+
diff --git a/dev-support/mini-submarine/conf/exclude-nodes.txt b/dev-support/mini-submarine/conf/exclude-nodes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..09697dce6e11859e38a9bfb321bfc72eb88b8ce6
--- /dev/null
+++ b/dev-support/mini-submarine/conf/exclude-nodes.txt
@@ -0,0 +1,15 @@
+# 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.
+
diff --git a/dev-support/mini-submarine/conf/excludeNodes.txt b/dev-support/mini-submarine/conf/excludeNodes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/dev-support/mini-submarine/conf/hdfs-site.xml b/dev-support/mini-submarine/conf/hdfs-site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a1d46b2d410496baa99a75e5dd902802a4021182
--- /dev/null
+++ b/dev-support/mini-submarine/conf/hdfs-site.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+ dfs.datanode.use.datanode.hostname
+ false
+
+
+
+ dfs.client.use.datanode.hostname
+ false
+
+
+
+ dfs.replication
+ 3
+
+
+
+ dfs.datanode.data.dir
+ file:///root/hdfs/datanode
+ DataNode directory
+
+
+
+ dfs.namenode.name.dir
+ file:///root/hdfs/namenode
+ NameNode directory for namespace and transaction logs storage.
+
+
+
+ dfs.namenode.datanode.registration.ip-hostname-check
+ false
+
+
diff --git a/dev-support/mini-submarine/conf/include-nodes.txt b/dev-support/mini-submarine/conf/include-nodes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..09697dce6e11859e38a9bfb321bfc72eb88b8ce6
--- /dev/null
+++ b/dev-support/mini-submarine/conf/include-nodes.txt
@@ -0,0 +1,15 @@
+# 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.
+
diff --git a/dev-support/mini-submarine/conf/mapred-site.xml b/dev-support/mini-submarine/conf/mapred-site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..22b86b9ea340ebf67672f5eeea84c3c360ea462e
--- /dev/null
+++ b/dev-support/mini-submarine/conf/mapred-site.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ mapreduce.framework.name
+ yarn
+
+
+ mapreduce.jobhistory.address
+ yarn-rm-0.yarn-rm.yarn-cluster.svc.cluster.local:10020
+
+
+ mapreduce.jobhistory.webapp.address
+ yarn-rm-0.yarn-rm.yarn-cluster.svc.cluster.local:19888
+
+
diff --git a/dev-support/mini-submarine/conf/node-resources.xml b/dev-support/mini-submarine/conf/node-resources.xml
new file mode 100644
index 0000000000000000000000000000000000000000..743c6d86970ed989f130516b01b4138126bc2897
--- /dev/null
+++ b/dev-support/mini-submarine/conf/node-resources.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/dev-support/mini-submarine/conf/resource-types.xml b/dev-support/mini-submarine/conf/resource-types.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4bc43c4dceb9f062c2f33023b64dbfde9cf267ef
--- /dev/null
+++ b/dev-support/mini-submarine/conf/resource-types.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/dev-support/mini-submarine/conf/setup-mysql.sh b/dev-support/mini-submarine/conf/setup-mysql.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d59632b2afaa0266d91c74206a61ad6bcb8d731e
--- /dev/null
+++ b/dev-support/mini-submarine/conf/setup-mysql.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# 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.
+
+# Install mariadb
+apt-get -y install mariadb-server
+service mysql start
+mysql -e "CREATE DATABASE submarine_test;"
+mysql -e "CREATE USER 'submarine_test'@'%' IDENTIFIED BY 'password_test';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'submarine_test'@'%';"
+mysql -e "use submarine_test; source /home/yarn/database/submarine.sql; source /home/yarn/database/submarine-data.sql;"
+
+mysql -e "CREATE DATABASE submarine;"
+mysql -e "CREATE USER 'submarine'@'%' IDENTIFIED BY 'password';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'submarine'@'%';"
+mysql -e "use submarine; source /home/yarn/database/submarine.sql; source /home/yarn/database/submarine-data.sql;"
+
+mysql -e "CREATE DATABASE metastore_test;"
+mysql -e "CREATE USER 'metastore_test'@'%' IDENTIFIED BY 'password_test';"
+mysql -e "GRANT ALL PRIVILEGES ON * . * TO 'metastore_test'@'%';"
+mysql -e "use metastore_test; source /home/yarn/database/metastore.sql;"
+
+mysql -e "CREATE DATABASE metastore;"
+mysql -e "CREATE USER 'metastore'@'%' IDENTIFIED BY 'password';"
+mysql -e "GRANT ALL PRIVILEGES ON * . * TO 'metastore'@'%';"
+mysql -e "use metastore; source /home/yarn/database/metastore.sql;"
diff --git a/dev-support/mini-submarine/conf/slaves b/dev-support/mini-submarine/conf/slaves
new file mode 100644
index 0000000000000000000000000000000000000000..63fb8bb82bbec04ec08ac7ce51d106afd797eecd
--- /dev/null
+++ b/dev-support/mini-submarine/conf/slaves
@@ -0,0 +1,16 @@
+# 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.
+
+localhost
diff --git a/dev-support/mini-submarine/conf/start-yarn-nm.sh b/dev-support/mini-submarine/conf/start-yarn-nm.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7fb683f90829cca027232be466813e04066750f0
--- /dev/null
+++ b/dev-support/mini-submarine/conf/start-yarn-nm.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# 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.
+
+
+# Start all yarn daemons. Run this on master node.
+
+echo "starting yarn daemons"
+
+bin=`dirname "${BASH_SOURCE-$0}"`
+bin=`cd "$bin"; pwd`
+
+DEFAULT_LIBEXEC_DIR="$bin"/../libexec
+HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
+. $HADOOP_LIBEXEC_DIR/yarn-config.sh
+
+# start resourceManager
+# "$bin"/yarn-daemon.sh --config $YARN_CONF_DIR start resourcemanager
+# start nodeManager
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR start nodemanager
+# start proxyserver
+#"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR start proxyserver
diff --git a/dev-support/mini-submarine/conf/start-yarn-rm.sh b/dev-support/mini-submarine/conf/start-yarn-rm.sh
new file mode 100755
index 0000000000000000000000000000000000000000..419e70cf8d629df1820fe60821b9bf3265ab5f04
--- /dev/null
+++ b/dev-support/mini-submarine/conf/start-yarn-rm.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# 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.
+
+
+# Start all yarn daemons. Run this on master node.
+
+echo "starting yarn daemons"
+
+bin=`dirname "${BASH_SOURCE-$0}"`
+bin=`cd "$bin"; pwd`
+
+DEFAULT_LIBEXEC_DIR="$bin"/../libexec
+HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
+. $HADOOP_LIBEXEC_DIR/yarn-config.sh
+
+# start resourceManager
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR start resourcemanager
+# start nodeManager
+# "$bin"/yarn-daemons.sh --config $YARN_CONF_DIR start nodemanager
+# start proxyserver
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR start proxyserver
diff --git a/dev-support/mini-submarine/conf/stop-yarn-nm.sh b/dev-support/mini-submarine/conf/stop-yarn-nm.sh
new file mode 100755
index 0000000000000000000000000000000000000000..03b57d60421fe7854944aef8ac0bbdd8d0f5fff2
--- /dev/null
+++ b/dev-support/mini-submarine/conf/stop-yarn-nm.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+# 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.
+
+
+# Start all yarn daemons. Run this on master node.
+
+echo "starting yarn daemons"
+
+bin=`dirname "${BASH_SOURCE-$0}"`
+bin=`cd "$bin"; pwd`
+
+DEFAULT_LIBEXEC_DIR="$bin"/../libexec
+HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
+. $HADOOP_LIBEXEC_DIR/yarn-config.sh
+
+# Stop nodeManager
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR stop nodemanager
diff --git a/dev-support/mini-submarine/conf/stop-yarn-rm.sh b/dev-support/mini-submarine/conf/stop-yarn-rm.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b5b42a6a7a36830992814eae78fef954025ff41f
--- /dev/null
+++ b/dev-support/mini-submarine/conf/stop-yarn-rm.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+# 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.
+
+
+# Start all yarn daemons. Run this on master node.
+
+echo "starting yarn daemons"
+
+bin=`dirname "${BASH_SOURCE-$0}"`
+bin=`cd "$bin"; pwd`
+
+DEFAULT_LIBEXEC_DIR="$bin"/../libexec
+HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR}
+. $HADOOP_LIBEXEC_DIR/yarn-config.sh
+
+# stop resourceManager
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR stop resourcemanager
+# stop proxyserver
+"$bin"/yarn-daemon.sh --config $YARN_CONF_DIR stop proxyserver
diff --git a/dev-support/mini-submarine/conf/submarine-env.sh b/dev-support/mini-submarine/conf/submarine-env.sh
new file mode 100644
index 0000000000000000000000000000000000000000..64ea5654e606f380376dc9b3749ecf73439f9091
--- /dev/null
+++ b/dev-support/mini-submarine/conf/submarine-env.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+
+# export JAVA_HOME=java
+
+# Debug Submarine server
+# export SUBMARINE_SERVER_JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
+
+# Set Submarine server memory
+# export SUBMARINE_SERVER_MEM="-Xms1024m -Xmx1024m -XX:MaxPermSize=512m"
+
+# Set Submarine server classpath. If you want to visit hdfs, just add hadoop
+# configuration path.
+export SUBMARINE_SERVER_CLASSPATH+=":/usr/local/hadoop/etc/hadoop"
diff --git a/dev-support/mini-submarine/conf/submarine-site.xml b/dev-support/mini-submarine/conf/submarine-site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f2236ae5a97818a20082fb946bf5dd574818de15
--- /dev/null
+++ b/dev-support/mini-submarine/conf/submarine-site.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ submarine.cluster.addr
+
+ submarine cluster address list, e.g. ip1:port1;ip2:port2;ip3:port3
+
+
+
+ submarine.server.addr
+ 0.0.0.0
+ Server address
+
+
+
+ submarine.server.port
+ 8080
+ Server port.
+
+
+
+ submarine.server.ssl
+ false
+ Should SSL be used by the submarine server?
+
+
+
+ submarine.server.ssl.port
+ 8443
+ Server ssl port. (used when ssl property is set to true)
+
+
+
+ submarine.server.ssl.client.auth
+ false
+ Should client authentication be used for SSL connections?
+
+
+
+ submarine.server.ssl.keystore.path
+ keystore
+ Path to keystore relative to submarine configuration directory
+
+
+
+ submarine.server.ssl.keystore.type
+ JKS
+ The format of the given keystore (e.g. JKS or PKCS12)
+
+
+
+ submarine.server.ssl.keystore.password
+ change me
+ Keystore password. Can be obfuscated by the Jetty Password tool
+
+
+
+
+
+ submarine.server.ssl.truststore.path
+ truststore
+ Path to truststore relative to submarine configuration directory. Defaults to the keystore path
+
+
+
+ submarine.server.ssl.truststore.type
+ JKS
+ The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type
+
+
+
+
+
+ workbench.web.war
+ ../submarine-workbench-web.war
+ Submarine workbench web war file path.
+
+
+
+ submarine.runtime.class
+ org.apache.submarine.server.submitter.yarn.YarnRuntimeFactory
+ RuntimeFactory for Submarine jobs
+
+
+
+ submarine.server.rpc.enabled
+ false
+ Run jobs using rpc server.
+
+
+
diff --git a/dev-support/mini-submarine/conf/tony.xml b/dev-support/mini-submarine/conf/tony.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f8c3ef86bd99c97d660872bab762f24e386b44e3
--- /dev/null
+++ b/dev-support/mini-submarine/conf/tony.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/dev-support/mini-submarine/conf/yarn-ds-docker.sh b/dev-support/mini-submarine/conf/yarn-ds-docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5232e03f11a74a20ff333e3c9aa551c4ed392a6e
--- /dev/null
+++ b/dev-support/mini-submarine/conf/yarn-ds-docker.sh
@@ -0,0 +1,18 @@
+# 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.
+
+#!/usr/bin/env bash
+DS=/usr/local/hadoop/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-${HADOOP_VER}.jar
+/usr/local/hadoop/bin/yarn jar ${DS} -jar ${DS} -shell_command "cat /proc/1/cgroup" -shell_env YARN_CONTAINER_RUNTIME_TYPE=docker -shell_env YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=library/ubuntu
diff --git a/dev-support/mini-submarine/conf/yarn-site.xml b/dev-support/mini-submarine/conf/yarn-site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1da453d39b5ffa3441315503a7f25cf3a31d5ff2
--- /dev/null
+++ b/dev-support/mini-submarine/conf/yarn-site.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+ yarn.resourcemanager.hostname
+ yarn-rm
+
+
+
+ yarn.resourcemanager.scheduler.class
+ org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
+
+
+
+ yarn.nodemanager.vmem-check-enabled
+ false
+
+
+
+ yarn.nodemanager.aux-services
+ mapreduce_shuffle
+
+
+
+ yarn.nodemanager.aux-services.mapreduce_shuffle.class
+ org.apache.hadoop.mapred.ShuffleHandler
+
+
+
+ List of directories to store localized files in.
+ yarn.nodemanager.local-dirs
+ /var/lib/hadoop-yarn/cache/${user.name}/nm-local-dir
+
+
+
+ Where to store container logs.
+ yarn.nodemanager.log-dirs
+ /var/log/hadoop-yarn/containers
+
+
+
+ Where to aggregate logs to.
+ yarn.nodemanager.remote-app-log-dir
+ /var/log/hadoop-yarn/apps
+
+
+
+ yarn.application.classpath
+
+ /usr/local/hadoop/etc/hadoop,
+ /usr/local/hadoop/share/hadoop/common/*,
+ /usr/local/hadoop/share/hadoop/common/lib/*,
+ /usr/local/hadoop/share/hadoop/hdfs/*,
+ /usr/local/hadoop/share/hadoop/hdfs/lib/*,
+ /usr/local/hadoop/share/hadoop/mapreduce/*,
+ /usr/local/hadoop/share/hadoop/mapreduce/lib/*,
+ /usr/local/hadoop/share/hadoop/yarn/*,
+ /usr/local/hadoop/share/hadoop/yarn/lib/*
+
+
+
+ yarn.log-aggregation-enable
+ true
+
+
+
+ yarn.log-aggregation.retain-seconds
+ 259200
+
+
+ yarn.log-aggregation.retain-check-interval-seconds
+ 3600
+
+
+ yarn.nodemanager.delete.debug-delay-sec
+ 86400
+
+
+ yarn.nodemanager.container-executor.class
+ org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor
+
+
+
+
+ yarn.nodemanager.linux-container-executor.group
+ hadoop
+
+
+ yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user
+ yarn
+
+
+
+ yarn.nodemanager.linux-container-executor.nonsecure-mode.limit-users
+ false
+
+
+
+ yarn.nodemanager.runtime.linux.allowed-runtimes
+ default,docker
+
+
+
+ yarn.nodemanager.runtime.linux.docker.allowed-container-networks
+ host,none,bridge
+
+
+ yarn.nodemanager.runtime.linux.docker.default-container-network
+ host
+
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.allowed
+ false
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.acl
+
+
+
+
+ yarn.nodemanager.runtime.linux.docker.capabilities
+ CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE
+
+
+
+ yarn.nodemanager.linux-container-executor.resources-handler.class
+ org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.mount
+ false
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.hierarchy
+ /hadoop-yarn
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.mount-path
+ /sys/fs/cgroup
+
+
+ yarn.nodemanager.resource.percentage-physical-cpu-limit
+ 100
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage
+ false
+
+
+
+
+
+ yarn.webapp.api-service.enable
+ true
+
+
+
diff --git a/dev-support/mini-submarine/spark-defaults-dynamic-allocation.conf b/dev-support/mini-submarine/spark-defaults-dynamic-allocation.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1cc360ea4cb5b92605b9188db02dd8d89b8aca7e
--- /dev/null
+++ b/dev-support/mini-submarine/spark-defaults-dynamic-allocation.conf
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+# Default system properties included when running spark-submit.
+# This is useful for setting default environmental settings.
+
+#spark.yarn.stagingDir /tmp/staging
+spark.yarn.preserve.staging.files true
+#spark.dynamicAllocation.enabled true
+spark.shuffle.service.enabled true
+spark.dynamicAllocation.minExecutors 1
+
+# Example:
+# spark.master spark://master:7077
+# spark.eventLog.enabled true
+# spark.eventLog.dir hdfs://namenode:8021/directory
+# spark.serializer org.apache.spark.serializer.KryoSerializer
+# spark.driver.memory 5g
+# spark.executor.extraJavaOptions -XX:+PrintGCDetails -Dkey=value -Dnumbers="one two three"
diff --git a/dev-support/mini-submarine/spark-script/pyspark-yarn.py b/dev-support/mini-submarine/spark-script/pyspark-yarn.py
new file mode 100755
index 0000000000000000000000000000000000000000..a28a5a206fc3f3002ffb1b9229123a159dd05b9b
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/pyspark-yarn.py
@@ -0,0 +1,32 @@
+# 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.
+
+
+from pyspark import SparkConf
+from pyspark import SparkContext
+
+conf = SparkConf()
+conf.setMaster('yarn-client')
+conf.setAppName('spark-yarn')
+sc = SparkContext(conf=conf)
+
+
+def mod(x):
+ #import time
+ #time.sleep(120)
+ return x
+
+rdd = sc.parallelize(range(1000)).map(mod).take(10)
+print rdd
diff --git a/dev-support/mini-submarine/spark-script/run_gpu_ds.sh b/dev-support/mini-submarine/spark-script/run_gpu_ds.sh
new file mode 100755
index 0000000000000000000000000000000000000000..26321a43d3697ffd5c91ed459e9c8bae2b18c347
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/run_gpu_ds.sh
@@ -0,0 +1,20 @@
+# 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.
+
+#!/usr/bin/env bash
+
+#JAR_PATH=/usr/local/hadoop/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-${HADOOP_VER}.jar
+
+#yarn jar $JAR_PATH -jar $JAR_PATH -shell_command "sleep 5" -master_resources memory-mb=512,vcores=2,nvidia.com/gpu=1 -container_resources memory-mb=512,vcores=1
diff --git a/dev-support/mini-submarine/spark-script/run_pyspark.sh b/dev-support/mini-submarine/spark-script/run_pyspark.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d834c87ef6f406c3a04f867e1b19159871394176
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/run_pyspark.sh
@@ -0,0 +1,25 @@
+# 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.
+
+#!/usr/bin/env bash
+SPARK_HOME=/opt/spark-${SPARK_VER}-bin-hadoop2.7
+${SPARK_HOME}/bin/spark-submit \
+--master yarn \
+--deploy-mode client \
+--driver-memory 1g \
+--executor-memory 2g \
+--num-executors 1 \
+--executor-cores 4 \
+./pyspark-yarn.py
diff --git a/dev-support/mini-submarine/spark-script/run_pyspark_docker.sh b/dev-support/mini-submarine/spark-script/run_pyspark_docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f4156c33dcca244b87c3d258208dd71d6ca3daf4
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/run_pyspark_docker.sh
@@ -0,0 +1,27 @@
+# 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.
+
+#!/usr/bin/env bash
+SPARK_HOME=/opt/spark-${SPARK_VER}-bin-hadoop2.7
+${SPARK_HOME}/bin/spark-submit \
+--master yarn \
+--deploy-mode client \
+--driver-memory 1g \
+--executor-memory 1g \
+--executor-cores 1 \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE= \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS=/etc/passwd:/etc/passwd:ro \
+./pyspark-yarn.py
diff --git a/dev-support/mini-submarine/spark-script/run_spark.sh b/dev-support/mini-submarine/spark-script/run_spark.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f44b12cc69964f6f981948697aa0c7364598c120
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/run_spark.sh
@@ -0,0 +1,26 @@
+# 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.
+
+#!/usr/bin/env bash
+
+SPARK_HOME=/opt/spark-${SPARK_VER}-bin-hadoop2.7
+${SPARK_HOME}/bin/spark-submit --class org.apache.spark.examples.SparkPi \
+--master yarn \
+--deploy-mode client \
+--driver-memory 512m \
+--executor-memory 512m \
+--executor-cores 1 \
+${SPARK_HOME}/examples/jars/spark-examples*.jar \
+10
diff --git a/dev-support/mini-submarine/spark-script/run_spark_docker.sh b/dev-support/mini-submarine/spark-script/run_spark_docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8b1078f1216d36631c439978de20ff1124df942a
--- /dev/null
+++ b/dev-support/mini-submarine/spark-script/run_spark_docker.sh
@@ -0,0 +1,29 @@
+# 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.
+
+#!/usr/bin/env bash
+SPARK_HOME=/opt/spark-${SPARK_VER}-bin-hadoop2.7
+${SPARK_HOME}/bin/spark-submit --class org.apache.spark.examples.SparkPi \
+--master yarn \
+--deploy-mode client \
+--driver-memory 512m \
+--executor-memory 512m \
+--executor-cores 1 \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE= \
+--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS=/etc/passwd:/etc/passwd:ro \
+--conf spark.dynamicAllocation.enabled=false \
+${SPARK_HOME}/examples/jars/spark-examples*.jar \
+10
diff --git a/dev-support/mini-submarine/submarine/build_python_virtual_env.sh b/dev-support/mini-submarine/submarine/build_python_virtual_env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fcb9d14e18b08ef4b718a1b5c74c30edf96185fb
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/build_python_virtual_env.sh
@@ -0,0 +1,37 @@
+# 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.
+
+#!/usr/bin/env bash
+wget https://files.pythonhosted.org/packages/33/bc/fa0b5347139cd9564f0d44ebd2b147ac97c36b2403943dbee8a25fd74012/virtualenv-16.0.0.tar.gz
+tar xf virtualenv-16.0.0.tar.gz
+
+# Make sure to install using Python 3, as TensorFlow only provides Python 3 artifacts
+python3 virtualenv-16.0.0/virtualenv.py venv
+. venv/bin/activate
+pip3 install tensorflow==1.13.1
+pip3 install torch==0.4.1
+pip3 install torchvision==0.1.8
+pip3 install mxnet==1.5.1
+pip3 install /opt/pysubmarine/.
+zip -r myvenv.zip venv
+deactivate
+
+# Building a Python virtual environment with TensorFlow 2
+python3 virtualenv-16.0.0/virtualenv.py tf2-venv
+. tf2-venv/bin/activate
+pip3 install tensorflow==2.1.0
+pip3 install tensorflow-datasets==2.1.0
+zip -r tf2-venv.zip tf2-venv
+deactivate
diff --git a/dev-support/mini-submarine/submarine/image_classification.py b/dev-support/mini-submarine/submarine/image_classification.py
new file mode 100644
index 0000000000000000000000000000000000000000..14eb68cd7935274ad6f95f30037e4bc4b5e64ce0
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/image_classification.py
@@ -0,0 +1,465 @@
+# 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.
+
+from __future__ import division
+
+import argparse
+import time
+import os
+import logging
+import random
+import tarfile
+
+import mxnet as mx
+from mxnet import gluon
+from mxnet import profiler
+from mxnet.gluon import nn
+from mxnet.gluon.model_zoo import vision as models
+from mxnet.gluon.data.vision import ImageFolderDataset
+from mxnet.gluon.data import DataLoader
+from mxnet.contrib.io import DataLoaderIter
+from mxnet import autograd as ag
+from mxnet.test_utils import get_mnist_iterator, get_cifar10
+from mxnet.metric import Accuracy, TopKAccuracy, CompositeEvalMetric
+import numpy as np
+
+# logging
+logging.basicConfig(level=logging.INFO)
+fh = logging.FileHandler('image-classification.log')
+logger = logging.getLogger()
+logger.addHandler(fh)
+formatter = logging.Formatter('%(message)s')
+fh.setFormatter(formatter)
+fh.setLevel(logging.DEBUG)
+logging.debug('\n%s', '-' * 100)
+formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+fh.setFormatter(formatter)
+
+# CLI
+parser = argparse.ArgumentParser(description='Train a model for image classification.')
+parser.add_argument('--dataset', type=str, default='cifar10',
+ help='dataset to use. options are mnist, cifar10, caltech101, imagenet and dummy.')
+parser.add_argument('--data-dir', type=str, default='',
+ help='training directory of imagenet images, contains train/val subdirs.')
+parser.add_argument('--num-worker', '-j', dest='num_workers', default=4, type=int,
+ help='number of workers for dataloader')
+parser.add_argument('--batch-size', type=int, default=32,
+ help='training batch size per device (CPU/GPU).')
+parser.add_argument('--gpus', type=str, default='',
+ help='ordinates of gpus to use, can be "0,1,2" or empty for cpu only.')
+parser.add_argument('--epochs', type=int, default=120,
+ help='number of training epochs.')
+parser.add_argument('--lr', type=float, default=0.1,
+ help='learning rate. default is 0.1.')
+parser.add_argument('--momentum', type=float, default=0.9,
+ help='momentum value for optimizer, default is 0.9.')
+parser.add_argument('--wd', type=float, default=0.0001,
+ help='weight decay rate. default is 0.0001.')
+parser.add_argument('--seed', type=int, default=123,
+ help='random seed to use. Default=123.')
+parser.add_argument('--mode', type=str,
+ help='mode in which to train the model. options are symbolic, imperative, hybrid')
+parser.add_argument('--model', type=str, required=True,
+ help='type of model to use. see vision_model for options.')
+parser.add_argument('--use_thumbnail', action='store_true',
+ help='use thumbnail or not in resnet. default is false.')
+parser.add_argument('--batch-norm', action='store_true',
+ help='enable batch normalization or not in vgg. default is false.')
+parser.add_argument('--use-pretrained', action='store_true',
+ help='enable using pretrained model from gluon.')
+parser.add_argument('--prefix', default='', type=str,
+ help='path to checkpoint prefix, default is current working dir')
+parser.add_argument('--start-epoch', default=0, type=int,
+ help='starting epoch, 0 for fresh training, > 0 to resume')
+parser.add_argument('--resume', type=str, default='',
+ help='path to saved weight where you want resume')
+parser.add_argument('--lr-factor', default=0.1, type=float,
+ help='learning rate decay ratio')
+parser.add_argument('--lr-steps', default='30,60,90', type=str,
+ help='list of learning rate decay epochs as in str')
+parser.add_argument('--dtype', default='float32', type=str,
+ help='data type, float32 or float16 if applicable')
+parser.add_argument('--save-frequency', default=10, type=int,
+ help='epoch frequence to save model, best model will always be saved')
+parser.add_argument('--kvstore', type=str, default='device',
+ help='kvstore to use for trainer/module.')
+parser.add_argument('--log-interval', type=int, default=50,
+ help='Number of batches to wait before logging.')
+parser.add_argument('--profile', action='store_true',
+ help='Option to turn on memory profiling for front-end, '\
+ 'and prints out the memory usage by python function at the end.')
+parser.add_argument('--builtin-profiler', type=int, default=0, help='Enable built-in profiler (0=off, 1=on)')
+opt = parser.parse_args()
+
+# global variables
+logger.info('Starting new image-classification task:, %s',opt)
+mx.random.seed(opt.seed)
+model_name = opt.model
+dataset_classes = {'mnist': 10, 'cifar10': 10, 'caltech101':101, 'imagenet': 1000, 'dummy': 1000}
+batch_size, dataset, classes = opt.batch_size, opt.dataset, dataset_classes[opt.dataset]
+context = [mx.gpu(int(i)) for i in opt.gpus.split(',')] if opt.gpus.strip() else [mx.cpu()]
+num_gpus = len(context)
+batch_size *= max(1, num_gpus)
+lr_steps = [int(x) for x in opt.lr_steps.split(',') if x.strip()]
+metric = CompositeEvalMetric([Accuracy(), TopKAccuracy(5)])
+kv = mx.kv.create(opt.kvstore)
+
+
+def get_cifar10_iterator(batch_size, data_shape, resize=-1, num_parts=1, part_index=0):
+ get_cifar10()
+
+ train = mx.io.ImageRecordIter(
+ path_imgrec = "data/cifar/train.rec",
+ resize = resize,
+ data_shape = data_shape,
+ batch_size = batch_size,
+ rand_crop = True,
+ rand_mirror = True,
+ num_parts=num_parts,
+ part_index=part_index)
+
+ val = mx.io.ImageRecordIter(
+ path_imgrec = "data/cifar/test.rec",
+ resize = resize,
+ rand_crop = False,
+ rand_mirror = False,
+ data_shape = data_shape,
+ batch_size = batch_size,
+ num_parts=num_parts,
+ part_index=part_index)
+
+ return train, val
+
+def get_imagenet_transforms(data_shape=224, dtype='float32'):
+ def train_transform(image, label):
+ image, _ = mx.image.random_size_crop(image, (data_shape, data_shape), 0.08, (3/4., 4/3.))
+ image = mx.nd.image.random_flip_left_right(image)
+ image = mx.nd.image.to_tensor(image)
+ image = mx.nd.image.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
+ return mx.nd.cast(image, dtype), label
+
+ def val_transform(image, label):
+ image = mx.image.resize_short(image, data_shape + 32)
+ image, _ = mx.image.center_crop(image, (data_shape, data_shape))
+ image = mx.nd.image.to_tensor(image)
+ image = mx.nd.image.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
+ return mx.nd.cast(image, dtype), label
+ return train_transform, val_transform
+
+def get_imagenet_iterator(root, batch_size, num_workers, data_shape=224, dtype='float32'):
+ """Dataset loader with preprocessing."""
+ train_dir = os.path.join(root, 'train')
+ train_transform, val_transform = get_imagenet_transforms(data_shape, dtype)
+ logging.info("Loading image folder %s, this may take a bit long...", train_dir)
+ train_dataset = ImageFolderDataset(train_dir, transform=train_transform)
+ train_data = DataLoader(train_dataset, batch_size, shuffle=True,
+ last_batch='discard', num_workers=num_workers)
+ val_dir = os.path.join(root, 'val')
+ if not os.path.isdir(os.path.expanduser(os.path.join(root, 'val', 'n01440764'))):
+ user_warning = 'Make sure validation images are stored in one subdir per category, a helper script is available at https://git.io/vNQv1'
+ raise ValueError(user_warning)
+ logging.info("Loading image folder %s, this may take a bit long...", val_dir)
+ val_dataset = ImageFolderDataset(val_dir, transform=val_transform)
+ val_data = DataLoader(val_dataset, batch_size, last_batch='keep', num_workers=num_workers)
+ return DataLoaderIter(train_data, dtype), DataLoaderIter(val_data, dtype)
+
+def get_caltech101_data():
+ url = "https://s3.us-east-2.amazonaws.com/mxnet-public/101_ObjectCategories.tar.gz"
+ dataset_name = "101_ObjectCategories"
+ data_folder = "data"
+ if not os.path.isdir(data_folder):
+ os.makedirs(data_folder)
+ tar_path = mx.gluon.utils.download(url, path=data_folder)
+ if (not os.path.isdir(os.path.join(data_folder, "101_ObjectCategories")) or
+ not os.path.isdir(os.path.join(data_folder, "101_ObjectCategories_test"))):
+ tar = tarfile.open(tar_path, "r:gz")
+ tar.extractall(data_folder)
+ tar.close()
+ print('Data extracted')
+ training_path = os.path.join(data_folder, dataset_name)
+ testing_path = os.path.join(data_folder, "{}_test".format(dataset_name))
+ return training_path, testing_path
+
+def get_caltech101_iterator(batch_size, num_workers, dtype):
+ def transform(image, label):
+ # resize the shorter edge to 224, the longer edge will be greater or equal to 224
+ resized = mx.image.resize_short(image, 224)
+ # center and crop an area of size (224,224)
+ cropped, crop_info = mx.image.center_crop(resized, (224, 224))
+ # transpose the channels to be (3,224,224)
+ transposed = mx.nd.transpose(cropped, (2, 0, 1))
+ return transposed, label
+
+ training_path, testing_path = get_caltech101_data()
+ dataset_train = ImageFolderDataset(root=training_path, transform=transform)
+ dataset_test = ImageFolderDataset(root=testing_path, transform=transform)
+
+ train_data = DataLoader(dataset_train, batch_size, shuffle=True, num_workers=num_workers)
+ test_data = DataLoader(dataset_test, batch_size, shuffle=False, num_workers=num_workers)
+ return DataLoaderIter(train_data), DataLoaderIter(test_data)
+
+class DummyIter(mx.io.DataIter):
+ def __init__(self, batch_size, data_shape, batches = 100):
+ super(DummyIter, self).__init__(batch_size)
+ self.data_shape = (batch_size,) + data_shape
+ self.label_shape = (batch_size,)
+ self.provide_data = [('data', self.data_shape)]
+ self.provide_label = [('softmax_label', self.label_shape)]
+ self.batch = mx.io.DataBatch(data=[mx.nd.zeros(self.data_shape)],
+ label=[mx.nd.zeros(self.label_shape)])
+ self._batches = 0
+ self.batches = batches
+
+ def next(self):
+ if self._batches < self.batches:
+ self._batches += 1
+ return self.batch
+ else:
+ self._batches = 0
+ raise StopIteration
+
+def dummy_iterator(batch_size, data_shape):
+ return DummyIter(batch_size, data_shape), DummyIter(batch_size, data_shape)
+
+class ImagePairIter(mx.io.DataIter):
+ def __init__(self, path, data_shape, label_shape, batch_size=64, flag=0, input_aug=None, target_aug=None):
+ super(ImagePairIter, self).__init__(batch_size)
+ self.data_shape = (batch_size,) + data_shape
+ self.label_shape = (batch_size,) + label_shape
+ self.input_aug = input_aug
+ self.target_aug = target_aug
+ self.provide_data = [('data', self.data_shape)]
+ self.provide_label = [('label', self.label_shape)]
+ is_image_file = lambda fn: any(fn.endswith(ext) for ext in [".png", ".jpg", ".jpeg"])
+ self.filenames = [os.path.join(path, x) for x in os.listdir(path) if is_image_file(x)]
+ self.count = 0
+ self.flag = flag
+ random.shuffle(self.filenames)
+
+ def next(self):
+ from PIL import Image
+ if self.count + self.batch_size <= len(self.filenames):
+ data = []
+ label = []
+ for i in range(self.batch_size):
+ fn = self.filenames[self.count]
+ self.count += 1
+ image = Image.open(fn).convert('YCbCr').split()[0]
+ if image.size[0] > image.size[1]:
+ image = image.transpose(Image.TRANSPOSE)
+ image = mx.nd.expand_dims(mx.nd.array(image), axis=2)
+ target = image.copy()
+ for aug in self.input_aug:
+ image = aug(image)
+ for aug in self.target_aug:
+ target = aug(target)
+ data.append(image)
+ label.append(target)
+
+ data = mx.nd.concat(*[mx.nd.expand_dims(d, axis=0) for d in data], dim=0)
+ label = mx.nd.concat(*[mx.nd.expand_dims(d, axis=0) for d in label], dim=0)
+ data = [mx.nd.transpose(data, axes=(0, 3, 1, 2)).astype('float32')/255]
+ label = [mx.nd.transpose(label, axes=(0, 3, 1, 2)).astype('float32')/255]
+
+ return mx.io.DataBatch(data=data, label=label)
+ else:
+ raise StopIteration
+
+ def reset(self):
+ self.count = 0
+ random.shuffle(self.filenames)
+
+def get_model(model, ctx, opt):
+ """Model initialization."""
+ kwargs = {'ctx': ctx, 'pretrained': opt.use_pretrained, 'classes': classes}
+ if model.startswith('resnet'):
+ kwargs['thumbnail'] = opt.use_thumbnail
+ elif model.startswith('vgg'):
+ kwargs['batch_norm'] = opt.batch_norm
+
+ net = models.get_model(model, **kwargs)
+ if opt.resume:
+ net.load_parameters(opt.resume)
+ elif not opt.use_pretrained:
+ if model in ['alexnet']:
+ net.initialize(mx.init.Normal())
+ else:
+ net.initialize(mx.init.Xavier(magnitude=2))
+ net.cast(opt.dtype)
+ return net
+
+net = get_model(opt.model, context, opt)
+
+def get_data_iters(dataset, batch_size, opt):
+ """get dataset iterators"""
+ if dataset == 'mnist':
+ train_data, val_data = get_mnist_iterator(batch_size, (1, 28, 28),
+ num_parts=kv.num_workers, part_index=kv.rank)
+ elif dataset == 'cifar10':
+ train_data, val_data = get_cifar10_iterator(batch_size, (3, 32, 32),
+ num_parts=kv.num_workers, part_index=kv.rank)
+ elif dataset == 'imagenet':
+ shape_dim = 299 if model_name == 'inceptionv3' else 224
+
+ if not opt.data_dir:
+ raise ValueError('Dir containing raw images in train/val is required for imagenet.'
+ 'Please specify "--data-dir"')
+
+ train_data, val_data = get_imagenet_iterator(opt.data_dir, batch_size,
+ opt.num_workers, shape_dim, opt.dtype)
+ elif dataset == 'caltech101':
+ train_data, val_data = get_caltech101_iterator(batch_size, opt.num_workers, opt.dtype)
+ elif dataset == 'dummy':
+ shape_dim = 299 if model_name == 'inceptionv3' else 224
+ train_data, val_data = dummy_iterator(batch_size, (3, shape_dim, shape_dim))
+ return train_data, val_data
+
+def test(ctx, val_data):
+ metric.reset()
+ val_data.reset()
+ for batch in val_data:
+ data = gluon.utils.split_and_load(batch.data[0].astype(opt.dtype, copy=False),
+ ctx_list=ctx, batch_axis=0)
+ label = gluon.utils.split_and_load(batch.label[0].astype(opt.dtype, copy=False),
+ ctx_list=ctx, batch_axis=0)
+ outputs = [net(X) for X in data]
+ metric.update(label, outputs)
+ return metric.get()
+
+def update_learning_rate(lr, trainer, epoch, ratio, steps):
+ """Set the learning rate to the initial value decayed by ratio every N epochs."""
+ new_lr = lr * (ratio ** int(np.sum(np.array(steps) < epoch)))
+ trainer.set_learning_rate(new_lr)
+ return trainer
+
+def save_checkpoint(epoch, top1, best_acc):
+ if opt.save_frequency and (epoch + 1) % opt.save_frequency == 0:
+ fname = os.path.join(opt.prefix, '%s_%d_acc_%.4f.params' % (opt.model, epoch, top1))
+ net.save_parameters(fname)
+ logger.info('[Epoch %d] Saving checkpoint to %s with Accuracy: %.4f', epoch, fname, top1)
+ if top1 > best_acc[0]:
+ best_acc[0] = top1
+ fname = os.path.join(opt.prefix, '%s_best.params' % (opt.model))
+ net.save_parameters(fname)
+ logger.info('[Epoch %d] Saving checkpoint to %s with Accuracy: %.4f', epoch, fname, top1)
+
+def train(opt, ctx):
+ if isinstance(ctx, mx.Context):
+ ctx = [ctx]
+
+ train_data, val_data = get_data_iters(dataset, batch_size, opt)
+ net.collect_params().reset_ctx(ctx)
+ trainer = gluon.Trainer(net.collect_params(), 'sgd',
+ optimizer_params={'learning_rate': opt.lr,
+ 'wd': opt.wd,
+ 'momentum': opt.momentum,
+ 'multi_precision': True},
+ kvstore=kv)
+ loss = gluon.loss.SoftmaxCrossEntropyLoss()
+
+ total_time = 0
+ num_epochs = 0
+ best_acc = [0]
+ for epoch in range(opt.start_epoch, opt.epochs):
+ trainer = update_learning_rate(opt.lr, trainer, epoch, opt.lr_factor, lr_steps)
+ tic = time.time()
+ train_data.reset()
+ metric.reset()
+ btic = time.time()
+ for i, batch in enumerate(train_data):
+ data = gluon.utils.split_and_load(batch.data[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0)
+ label = gluon.utils.split_and_load(batch.label[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0)
+ outputs = []
+ Ls = []
+ with ag.record():
+ for x, y in zip(data, label):
+ z = net(x)
+ L = loss(z, y)
+ # store the loss and do backward after we have done forward
+ # on all GPUs for better speed on multiple GPUs.
+ Ls.append(L)
+ outputs.append(z)
+ ag.backward(Ls)
+ trainer.step(batch.data[0].shape[0])
+ metric.update(label, outputs)
+ if opt.log_interval and not (i+1)%opt.log_interval:
+ name, acc = metric.get()
+ logger.info('Epoch[%d] Batch [%d]\tSpeed: %f samples/sec\t%s=%f, %s=%f'%(
+ epoch, i, batch_size/(time.time()-btic), name[0], acc[0], name[1], acc[1]))
+ btic = time.time()
+
+ epoch_time = time.time()-tic
+
+ # First epoch will usually be much slower than the subsequent epics,
+ # so don't factor into the average
+ if num_epochs > 0:
+ total_time = total_time + epoch_time
+ num_epochs = num_epochs + 1
+
+ name, acc = metric.get()
+ logger.info('[Epoch %d] training: %s=%f, %s=%f'%(epoch, name[0], acc[0], name[1], acc[1]))
+ logger.info('[Epoch %d] time cost: %f'%(epoch, epoch_time))
+ name, val_acc = test(ctx, val_data)
+ logger.info('[Epoch %d] validation: %s=%f, %s=%f'%(epoch, name[0], val_acc[0], name[1], val_acc[1]))
+
+ # save model if meet requirements
+ save_checkpoint(epoch, val_acc[0], best_acc)
+ if num_epochs > 1:
+ print('Average epoch time: {}'.format(float(total_time)/(num_epochs - 1)))
+
+def main():
+ if opt.builtin_profiler > 0:
+ profiler.set_config(profile_all=True, aggregate_stats=True)
+ profiler.set_state('run')
+ if opt.mode == 'symbolic':
+ data = mx.sym.var('data')
+ if opt.dtype == 'float16':
+ data = mx.sym.Cast(data=data, dtype=np.float16)
+ out = net(data)
+ if opt.dtype == 'float16':
+ out = mx.sym.Cast(data=out, dtype=np.float32)
+ softmax = mx.sym.SoftmaxOutput(out, name='softmax')
+ mod = mx.mod.Module(softmax, context=context)
+ train_data, val_data = get_data_iters(dataset, batch_size, opt)
+ mod.fit(train_data,
+ eval_data=val_data,
+ num_epoch=opt.epochs,
+ kvstore=kv,
+ batch_end_callback = mx.callback.Speedometer(batch_size, max(1, opt.log_interval)),
+ epoch_end_callback = mx.callback.do_checkpoint('image-classifier-%s'% opt.model),
+ optimizer = 'sgd',
+ optimizer_params = {'learning_rate': opt.lr, 'wd': opt.wd, 'momentum': opt.momentum, 'multi_precision': True},
+ initializer = mx.init.Xavier(magnitude=2))
+ mod.save_parameters('image-classifier-%s-%d-final.params'%(opt.model, opt.epochs))
+ else:
+ if opt.mode == 'hybrid':
+ net.hybridize()
+ train(opt, context)
+ if opt.builtin_profiler > 0:
+ profiler.set_state('stop')
+ print(profiler.dumps())
+
+if __name__ == '__main__':
+ if opt.profile:
+ import hotshot, hotshot.stats
+ prof = hotshot.Profile('image-classifier-%s-%s.prof'%(opt.model, opt.mode))
+ prof.runcall(main)
+ prof.close()
+ stats = hotshot.stats.load('image-classifier-%s-%s.prof'%(opt.model, opt.mode))
+ stats.strip_dirs()
+ stats.sort_stats('cumtime', 'calls')
+ stats.print_stats()
+ else:
+ main()
diff --git a/dev-support/mini-submarine/submarine/mnist_distributed.py b/dev-support/mini-submarine/submarine/mnist_distributed.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfa0beb5b281a8db8e625779dd9da3141149e702
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/mnist_distributed.py
@@ -0,0 +1,275 @@
+# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==============================================================================
+
+"""A deep MNIST classifier using convolutional layers.
+
+This example was adapted from
+https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_deep.py.
+
+Each worker reads the full MNIST dataset and asynchronously trains a CNN with dropout and using the Adam optimizer,
+updating the model parameters on shared parameter servers.
+
+The current training accuracy is printed out after every 100 steps.
+"""
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+from tensorflow.examples.tutorials.mnist import input_data
+
+import json
+import logging
+import os
+import sys
+
+import tensorboard.program as tb_program
+import tensorflow as tf
+# import submarine
+
+# Environment variable containing port to launch TensorBoard on, set by TonY.
+TB_PORT_ENV_VAR = 'TB_PORT'
+
+# mnist data url
+tf.flags.DEFINE_string('mnist_data_url', '',
+ 'Url for mnist handwritten digits dataset')
+
+# Input/output directories
+tf.flags.DEFINE_string('data_dir', '/tmp/tensorflow/mnist/input_data',
+ 'Directory for storing input data')
+tf.flags.DEFINE_string('working_dir', '/tmp/tensorflow/mnist/working_dir',
+ 'Directory under which events and output will be '
+ 'stored (in separate subdirectories).')
+
+# Training parameters
+tf.flags.DEFINE_integer("steps", 1500,
+ "The number of training steps to execute.")
+tf.flags.DEFINE_integer("batch_size", 64, "The batch size per step.")
+
+FLAGS = tf.flags.FLAGS
+
+
+def deepnn(x):
+ """deepnn builds the graph for a deep net for classifying digits.
+
+ Args:
+ x: an input tensor with the dimensions (N_examples, 784), where 784 is the
+ number of pixels in a standard MNIST image.
+
+ Returns:
+ A tuple (y, keep_prob). y is a tensor of shape (N_examples, 10), with values
+ equal to the logits of classifying the digit into one of 10 classes (the
+ digits 0-9). keep_prob is a scalar placeholder for the probability of
+ dropout.
+ """
+ # Reshape to use within a convolutional neural net.
+ # Last dimension is for "features" - there is only one here, since images are
+ # grayscale -- it would be 3 for an RGB image, 4 for RGBA, etc.
+ with tf.name_scope('reshape'):
+ x_image = tf.reshape(x, [-1, 28, 28, 1])
+
+ # First convolutional layer - maps one grayscale image to 32 feature maps.
+ with tf.name_scope('conv1'):
+ W_conv1 = weight_variable([5, 5, 1, 32])
+ b_conv1 = bias_variable([32])
+ h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
+
+ # Pooling layer - downsamples by 2X.
+ with tf.name_scope('pool1'):
+ h_pool1 = max_pool_2x2(h_conv1)
+
+ # Second convolutional layer -- maps 32 feature maps to 64.
+ with tf.name_scope('conv2'):
+ W_conv2 = weight_variable([5, 5, 32, 64])
+ b_conv2 = bias_variable([64])
+ h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
+
+ # Second pooling layer.
+ with tf.name_scope('pool2'):
+ h_pool2 = max_pool_2x2(h_conv2)
+
+ # Fully connected layer 1 -- after 2 round of downsampling, our 28x28 image
+ # is down to 7x7x64 feature maps -- maps this to 1024 features.
+ with tf.name_scope('fc1'):
+ W_fc1 = weight_variable([7 * 7 * 64, 1024])
+ b_fc1 = bias_variable([1024])
+
+ h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
+ h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
+
+ # Dropout - controls the complexity of the model, prevents co-adaptation of
+ # features.
+ with tf.name_scope('dropout'):
+ keep_prob = tf.placeholder(tf.float32)
+ h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
+
+ # Map the 1024 features to 10 classes, one for each digit
+ with tf.name_scope('fc2'):
+ W_fc2 = weight_variable([1024, 10])
+ b_fc2 = bias_variable([10])
+
+ y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
+ return y_conv, keep_prob
+
+
+def conv2d(x, W):
+ """conv2d returns a 2d convolution layer with full stride."""
+ return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
+
+
+def max_pool_2x2(x):
+ """max_pool_2x2 downsamples a feature map by 2X."""
+ return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
+ strides=[1, 2, 2, 1], padding='SAME')
+
+
+def weight_variable(shape):
+ """weight_variable generates a weight variable of a given shape."""
+ initial = tf.truncated_normal(shape, stddev=0.1)
+ return tf.Variable(initial)
+
+
+def bias_variable(shape):
+ """bias_variable generates a bias variable of a given shape."""
+ initial = tf.constant(0.1, shape=shape)
+ return tf.Variable(initial)
+
+
+def create_model():
+ """Creates our model and returns the target nodes to be run or populated"""
+ # Create the model
+ x = tf.placeholder(tf.float32, [None, 784])
+
+ # Define loss and optimizer
+ y_ = tf.placeholder(tf.int64, [None])
+
+ # Build the graph for the deep net
+ y_conv, keep_prob = deepnn(x)
+
+ with tf.name_scope('loss'):
+ cross_entropy = tf.losses.sparse_softmax_cross_entropy(labels=y_,
+ logits=y_conv)
+ cross_entropy = tf.reduce_mean(cross_entropy)
+
+ global_step = tf.train.get_or_create_global_step()
+ with tf.name_scope('adam_optimizer'):
+ train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy,
+ global_step=global_step)
+
+ with tf.name_scope('accuracy'):
+ correct_prediction = tf.equal(tf.argmax(y_conv, 1), y_)
+ correct_prediction = tf.cast(correct_prediction, tf.float32)
+ accuracy = tf.reduce_mean(correct_prediction)
+
+ tf.summary.scalar('cross_entropy_loss', cross_entropy)
+ tf.summary.scalar('accuracy', accuracy)
+
+ merged = tf.summary.merge_all()
+
+ return x, y_, keep_prob, global_step, train_step, accuracy, merged
+
+
+def start_tensorboard(logdir):
+ tb = tb_program.TensorBoard()
+ port = int(os.getenv(TB_PORT_ENV_VAR, 6006))
+ tb.configure(logdir=logdir, port=port)
+ tb.launch()
+ logging.info("Starting TensorBoard with --logdir=%s" % logdir)
+
+
+def main(_):
+ logging.getLogger().setLevel(logging.INFO)
+
+ cluster_spec_str = os.environ["CLUSTER_SPEC"]
+ cluster_spec = json.loads(cluster_spec_str)
+ ps_hosts = cluster_spec['ps']
+ worker_hosts = cluster_spec['worker']
+
+ # Create a cluster from the parameter server and worker hosts.
+ cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})
+
+ # Create and start a server for the local task.
+ job_name = os.environ["JOB_NAME"]
+ task_index = int(os.environ["TASK_INDEX"])
+ server = tf.train.Server(cluster, job_name=job_name, task_index=task_index)
+
+ if job_name == "ps":
+ server.join()
+ elif job_name == "worker":
+ # Create our model graph. Assigns ops to the local worker by default.
+ with tf.device(tf.train.replica_device_setter(
+ worker_device="/job:worker/task:%d" % task_index,
+ cluster=cluster)):
+ features, labels, keep_prob, global_step, train_step, accuracy, \
+ merged = create_model()
+
+ if task_index is 0: # chief worker
+ tf.gfile.MakeDirs(FLAGS.working_dir)
+ start_tensorboard(FLAGS.working_dir)
+
+ # The StopAtStepHook handles stopping after running given steps.
+ hooks = [tf.train.StopAtStepHook(num_steps=FLAGS.steps)]
+
+ # Filter all connections except that between ps and this worker to
+ # avoid hanging issues when one worker finishes. We are using
+ # asynchronous training so there is no need for the workers to
+ # communicate.
+ config_proto = tf.ConfigProto(
+ device_filters=['/job:ps', '/job:worker/task:%d' % task_index])
+
+ with tf.train.MonitoredTrainingSession(master=server.target,
+ is_chief=(task_index == 0),
+ checkpoint_dir=FLAGS.working_dir,
+ hooks=hooks,
+ config=config_proto) as sess:
+ # Import data
+ logging.info('Extracting and loading input data...')
+ # Use a different data dir name to workaround "file already exists issue" when downloading dataset in the same single node
+ if FLAGS.mnist_data_url == '':
+ logging.info('Getting mnist data from default url')
+ mnist = input_data.read_data_sets(FLAGS.data_dir + str(task_index))
+ else:
+ logging.info('Getting mnist data from ' + FLAGS.mnist_data_url)
+ mnist = input_data.read_data_sets(FLAGS.data_dir + str(task_index),
+ source_url=FLAGS.mnist_data_url)
+
+ # Train
+ logging.info('Starting training')
+ i = 0
+ while not sess.should_stop():
+ # Before use submarine-sdk, start Mysql server first
+ # submarine.log_param("batch_size", FLAGS.batch_size)
+ batch = mnist.train.next_batch(FLAGS.batch_size)
+ if i % 100 == 0:
+ step, _, train_accuracy = sess.run(
+ [global_step, train_step, accuracy],
+ feed_dict={features: batch[0], labels: batch[1],
+ keep_prob: 1.0})
+ logging.info('Step %d, training accuracy: %g' % (
+ step, train_accuracy))
+ # Before use submarine-sdk, start Mysql server first
+ # submarine.log_metric("accuracy", train_accuracy, i)
+ else:
+ sess.run([global_step, train_step],
+ feed_dict={features: batch[0], labels: batch[1],
+ keep_prob: 0.5})
+ i += 1
+
+ logging.info('Done training!')
+ sys.exit()
+
+
+if __name__ == '__main__':
+ tf.app.run()
diff --git a/dev-support/mini-submarine/submarine/mnist_distributed_tf2.py b/dev-support/mini-submarine/submarine/mnist_distributed_tf2.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f880e6f5b814924aff063b2964c5888ab13e7b0
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/mnist_distributed_tf2.py
@@ -0,0 +1,98 @@
+# 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.
+
+import os
+import json
+import tensorflow as tf
+import tensorflow_datasets as tfds
+
+BATCH_SIZE = 64
+BUFFER_SIZE = 10000
+LEARNING_RATE = 1e-4
+
+def get_task_name():
+ cluster_spec = os.environ.get("CLUSTER_SPEC", None)
+ task_name = ''
+ if cluster_spec:
+ cluster_spec = json.loads(cluster_spec)
+ job_index = os.environ["TASK_INDEX"]
+ job_name = os.environ["JOB_NAME"]
+ task_name = job_name + '_' + job_index
+
+ return task_name
+
+def input_fn(mode, input_context=None):
+ datasets, info = tfds.load(name='mnist',
+ data_dir='/tmp/' + get_task_name() + '/data',
+ with_info=True,
+ as_supervised=True)
+
+ mnist_dataset = (datasets['train'] if mode == tf.estimator.ModeKeys.TRAIN
+ else datasets['test'])
+
+ def scale(image, label):
+ image = tf.cast(image, tf.float32)
+ image /= 255
+ return image, label
+
+ if input_context:
+ mnist_dataset = mnist_dataset.shard(
+ input_context.num_input_pipelines,
+ input_context.input_pipeline_id)
+
+ return mnist_dataset.map(scale).cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
+
+def model_fn(features, labels, mode):
+ model = tf.keras.Sequential([
+ tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
+ tf.keras.layers.MaxPooling2D(),
+ tf.keras.layers.Flatten(),
+ tf.keras.layers.Dense(64, activation='relu'),
+ tf.keras.layers.Dense(10)
+ ])
+
+ logits = model(features, training=False)
+
+ if mode == tf.estimator.ModeKeys.PREDICT:
+ predictions = {'logits': logits}
+ return tf.estimator.EstimatorSpec(labels=labels, predictions=predictions)
+
+ optimizer = tf.compat.v1.train.GradientDescentOptimizer(
+ learning_rate=LEARNING_RATE)
+ loss = tf.keras.losses.SparseCategoricalCrossentropy(
+ from_logits=True, reduction=tf.keras.losses.Reduction.NONE)(labels, logits)
+ loss = tf.reduce_sum(loss) * (1. / BATCH_SIZE)
+ if mode == tf.estimator.ModeKeys.EVAL:
+ return tf.estimator.EstimatorSpec(mode, loss=loss)
+
+ return tf.estimator.EstimatorSpec(
+ mode=mode,
+ loss=loss,
+ train_op=optimizer.minimize(
+ loss, tf.compat.v1.train.get_or_create_global_step()))
+
+if __name__ == '__main__':
+ strategy = tf.distribute.experimental.ParameterServerStrategy()
+ config = tf.estimator.RunConfig(train_distribute=strategy)
+ estimator = tf.estimator.Estimator(
+ model_fn=model_fn,
+ model_dir='/tmp/model',
+ config=config)
+ train_spec = tf.estimator.TrainSpec(input_fn)
+ eval_spec = tf.estimator.EvalSpec(input_fn)
+ tf.estimator.train_and_evaluate(
+ estimator,
+ train_spec,
+ eval_spec)
diff --git a/dev-support/mini-submarine/submarine/pytorch_mnist_distributed.py b/dev-support/mini-submarine/submarine/pytorch_mnist_distributed.py
new file mode 100644
index 0000000000000000000000000000000000000000..667603aefb9570c2bf1a044e35679af22ebb7e45
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/pytorch_mnist_distributed.py
@@ -0,0 +1,242 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==============================================================================
+
+"""A deep MNIST classifier using convolutional layers.
+
+This example was adapted from
+https://pytorch.org/docs/master/distributed.html
+https://pytorch.org/tutorials/intermediate/dist_tuto.html
+https://github.com/narumiruna/pytorch-distributed-example/blob/master/mnist/main.py
+
+Each worker reads the full MNIST dataset and asynchronously trains a CNN with dropout and using the Adam optimizer,
+updating the model parameters on shared parameter servers.
+
+The current training accuracy is printed out after every 100 steps.
+"""
+
+from __future__ import division, print_function
+
+import argparse
+
+import os
+import torch
+import torch.nn.functional as F
+from torch import distributed, nn
+from torch.utils import data
+from torch.utils.data.distributed import DistributedSampler
+from torchvision import datasets, transforms
+
+
+class AverageMeter(object):
+
+ def __init__(self):
+ self.sum = 0
+ self.count = 0
+
+ def update(self, value, number):
+ self.sum += value * number
+ self.count += number
+
+ @property
+ def average(self):
+ return self.sum / self.count
+
+
+class AccuracyMeter(object):
+
+ def __init__(self):
+ self.correct = 0
+ self.count = 0
+
+ def update(self, output, label):
+ predictions = output.data.argmax(dim=1)
+ correct = predictions.eq(label.data).sum().item()
+
+ self.correct += correct
+ self.count += output.size(0)
+
+ @property
+ def accuracy(self):
+ return self.correct / self.count
+
+
+class Trainer(object):
+
+ def __init__(self, net, optimizer, train_loader, test_loader, device):
+ self.net = net
+ self.optimizer = optimizer
+ self.train_loader = train_loader
+ self.test_loader = test_loader
+ self.device = device
+
+ def train(self):
+ train_loss = AverageMeter()
+ train_acc = AccuracyMeter()
+
+ self.net.train()
+
+ for data, label in self.train_loader:
+ data = data.to(self.device)
+ label = label.to(self.device)
+
+ output = self.net(data)
+ loss = F.cross_entropy(output, label)
+
+ self.optimizer.zero_grad()
+ loss.backward()
+ # average the gradients
+ self.average_gradients()
+ self.optimizer.step()
+
+ train_loss.update(loss.item(), data.size(0))
+ train_acc.update(output, label)
+
+ return train_loss.average, train_acc.accuracy
+
+ def evaluate(self):
+ test_loss = AverageMeter()
+ test_acc = AccuracyMeter()
+
+ self.net.eval()
+
+ with torch.no_grad():
+ for data, label in self.test_loader:
+ data = data.to(self.device)
+ label = label.to(self.device)
+
+ output = self.net(data)
+ loss = F.cross_entropy(output, label)
+
+ test_loss.update(loss.item(), data.size(0))
+ test_acc.update(output, label)
+
+ return test_loss.average, test_acc.accuracy
+
+ def average_gradients(self):
+ world_size = distributed.get_world_size()
+
+ for p in self.net.parameters():
+ group = distributed.new_group(ranks=list(range(world_size)))
+
+ tensor = p.grad.data.cpu()
+
+ distributed.all_reduce(
+ tensor, op=distributed.reduce_op.SUM, group=group)
+
+ tensor /= float(world_size)
+
+ p.grad.data = tensor.to(self.device)
+
+
+class Net(nn.Module):
+
+ def __init__(self):
+ super(Net, self).__init__()
+ self.fc = nn.Linear(784, 10)
+
+ def forward(self, x):
+ return self.fc(x.view(x.size(0), -1))
+
+
+def get_dataloader(root, batch_size):
+ transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Normalize((0.13066047740239478,), (0.3081078087569972,))
+ ])
+
+ train_set = datasets.MNIST(
+ root, train=True, transform=transform, download=True)
+ sampler = DistributedSampler(train_set)
+
+ train_loader = data.DataLoader(
+ train_set,
+ batch_size=batch_size,
+ shuffle=(sampler is None),
+ sampler=sampler)
+
+ test_loader = data.DataLoader(
+ datasets.MNIST(root, train=False, transform=transform, download=True),
+ batch_size=batch_size,
+ shuffle=False)
+
+ return train_loader, test_loader
+
+
+def solve(args):
+ device = torch.device('cuda' if args.cuda else 'cpu')
+
+ net = Net().to(device)
+
+ optimizer = torch.optim.Adam(net.parameters(), lr=args.learning_rate)
+
+ train_loader, test_loader = get_dataloader(args.root, args.batch_size)
+
+ trainer = Trainer(net, optimizer, train_loader, test_loader, device)
+
+ for epoch in range(1, args.epochs + 1):
+ train_loss, train_acc = trainer.train()
+ test_loss, test_acc = trainer.evaluate()
+
+ print(
+ 'Epoch: {}/{},'.format(epoch, args.epochs),
+ 'train loss: {:.6f}, train acc: {:.6f}, test loss: {:.6f}, test acc: {:.6f}.'.
+ format(train_loss, train_acc, test_loss, test_acc))
+
+
+def init_process(args):
+ distributed.init_process_group(
+ backend=args.backend,
+ init_method=args.init_method,
+ rank=args.rank,
+ world_size=args.world_size)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--backend',
+ type=str,
+ default='tcp',
+ help='Name of the backend to use.')
+ parser.add_argument(
+ '--init-method',
+ '-i',
+ type=str,
+ default=os.environ.get('INIT_METHOD', 'tcp://127.0.0.1:23456'),
+ help='URL specifying how to initialize the package.')
+ parser.add_argument(
+ '--rank', '-r',
+ type=int,
+ default=int(os.environ.get('RANK')),
+ help='Rank of the current process.')
+ parser.add_argument(
+ '--world-size',
+ '-s',
+ type=int,
+ default=int(os.environ.get('WORLD')),
+ help='Number of processes participating in the job.')
+ parser.add_argument('--epochs', type=int, default=20)
+ parser.add_argument('--no-cuda', action='store_true')
+ parser.add_argument('--learning-rate', '-lr', type=float, default=1e-3)
+ parser.add_argument('--root', type=str, default='data')
+ parser.add_argument('--batch-size', type=int, default=128)
+ args = parser.parse_args()
+ args.cuda = torch.cuda.is_available() and not args.no_cuda
+ print(args)
+
+ init_process(args)
+ solve(args)
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/dev-support/mini-submarine/submarine/run_customized_submarine-all_mnist.sh b/dev-support/mini-submarine/submarine/run_customized_submarine-all_mnist.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d08a7b981b205336019f3ed65d393e6b2e650c39
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_customized_submarine-all_mnist.sh
@@ -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.
+
+#!/usr/bin/env bash
+
+# Need to modify environment variables based on version
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+DEBUG_PORT=8000
+if [ "$DEBUG" ]; then
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+while getopts 'd:' OPT; do
+ case $OPT in
+ d)
+ DATA_URL="$OPTARG";;
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [[ -n "$DATA_URL" ]]; then
+ WORKER_CMD="myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode --mnist_data_url ${DATA_URL}"
+else
+ WORKER_CMD="myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode"
+fi
+
+SUBMARINE_VERSION=${SUBMARINE_VER:-"0.5.0"}
+
+HADOOP_VERSION=2.9
+
+${JAVA_CMD} -cp /tmp/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar:/usr/local/hadoop/etc/hadoop \
+org.apache.submarine.client.cli.Cli job run --name tf-job-002 \
+--framework tensorflow \
+--verbose \
+--input_path "" \
+--num_workers 2 \
+--worker_resources memory=1G,vcores=1 \
+--num_ps 1 \
+--ps_resources memory=1G,vcores=1 \
+--worker_launch_cmd "${WORKER_CMD}" \
+--ps_launch_cmd "myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode" \
+--insecure \
+--conf tony.containers.resources=/home/yarn/submarine/myvenv.zip#archive,/home/yarn/submarine/mnist_distributed.py,/tmp/submarine-dist-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar
diff --git a/dev-support/mini-submarine/submarine/run_submarine_mnist_tf2_tony.sh b/dev-support/mini-submarine/submarine/run_submarine_mnist_tf2_tony.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b12efbff9809c93c91e2d6097b0cbdf601bbc9f0
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_submarine_mnist_tf2_tony.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+# 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.
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ if [ -n "$2" ]; then
+ DEBUG_PORT=$2
+ shift
+ fi
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+if [ "$DEBUG" ]; then
+ if [ -z "$DEBUG_PORT" ]; then
+ DEBUG_PORT=8000
+ fi
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+SUBMARINE_VERSION=0.5.0
+HADOOP_VERSION=2.9
+SUBMARINE_PATH=/opt/submarine-current
+HADOOP_CONF_PATH=/usr/local/hadoop/etc/hadoop
+
+${JAVA_CMD} -cp "$("${HADOOP_COMMON_HOME}"/bin/hadoop classpath --glob)":${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-"${HADOOP_VERSION}".jar:${HADOOP_CONF_PATH} \
+ org.apache.submarine.client.cli.Cli job run --name tf2-job-001 \
+ --framework tensorflow \
+ --input_path "" \
+ --num_workers 2 \
+ --worker_resources memory=1G,vcores=1 \
+ --num_ps 1 \
+ --ps_resources memory=1G,vcores=1 \
+ --worker_launch_cmd "tf2-venv.zip/tf2-venv/bin/python mnist_distributed_tf2.py" \
+ --ps_launch_cmd "tf2-venv.zip/tf2-venv/bin/python mnist_distributed_tf2.py" \
+ --insecure \
+ --verbose \
+ --conf tony.containers.resources=/home/yarn/submarine/tf2-venv.zip#archive,/home/yarn/submarine/mnist_distributed_tf2.py,${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-"${HADOOP_VERSION}".jar
diff --git a/dev-support/mini-submarine/submarine/run_submarine_mnist_tony.sh b/dev-support/mini-submarine/submarine/run_submarine_mnist_tony.sh
new file mode 100755
index 0000000000000000000000000000000000000000..272ac320d2a74f233b74955650a700e8e109e3df
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_submarine_mnist_tony.sh
@@ -0,0 +1,90 @@
+# 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.
+
+#!/usr/bin/env bash
+
+# Below are configurable variables, please adapt base on your local environment.
+# Version of submarine jar
+SUBMARINE_VERSION=${SUBMARINE_VER:-"0.5.0"}
+
+# Version of affiliated Hadoop version for this Submarine jar.
+SUBMARINE_HADOOP_VERSION=2.9
+
+# Path to the submarine jars.
+SUBMARINE_PATH=/opt/submarine-current
+
+# Similar to HADOOP_CONF_DIR, location of the Hadoop configuration directory
+HADOOP_CONF_PATH=/usr/local/hadoop/etc/hadoop
+
+# Path to the MNIST example.
+MNIST_PATH=/home/yarn/submarine
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+DEBUG_PORT=8000
+if [ "$DEBUG" ]; then
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+while getopts 'd:c' OPT; do
+ case $OPT in
+ d)
+ DATA_URL="$OPTARG";;
+ c)
+ USE_DOCKER=1;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [[ -n "$DATA_URL" ]]; then
+ WORKER_CMD="venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode --mnist_data_url ${DATA_URL}"
+else
+ WORKER_CMD="venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode"
+fi
+
+if [[ -n "$USE_DOCKER" ]]; then
+ WORKER_CMD="/opt/$WORKER_CMD"
+ # tony-mnist-tf-1.13.1:0.0.1 is built from the Dockerfile.tony.tf.mnist.tf_1.13.1 under docs/helper/docker/tensorflow/mnist
+ DOCKER_CONF="--conf tony.docker.containers.image=tony-mnist-tf-1.13.1:0.0.1 --conf tony.docker.enabled=true"
+else
+ WORKER_CMD="myvenv.zip/$WORKER_CMD"
+fi
+
+${JAVA_CMD} -cp $(${HADOOP_COMMON_HOME}/bin/hadoop classpath --glob):${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${SUBMARINE_HADOOP_VERSION}.jar:${HADOOP_CONF_PATH} \
+ org.apache.submarine.client.cli.Cli job run --name tf-job-001 \
+ --framework tensorflow \
+ --verbose \
+ --input_path "" \
+ --num_workers 2 \
+ --worker_resources memory=1G,vcores=1 \
+ --num_ps 1 \
+ --ps_resources memory=1G,vcores=1 \
+ --worker_launch_cmd "${WORKER_CMD}" \
+ --ps_launch_cmd "myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode" \
+ --insecure \
+ --conf tony.containers.resources=${MNIST_PATH}/myvenv.zip#archive,${MNIST_PATH}/mnist_distributed.py,${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${SUBMARINE_HADOOP_VERSION}.jar \
+ $DOCKER_CONF
diff --git a/dev-support/mini-submarine/submarine/run_submarine_mnist_tony_rpc.sh b/dev-support/mini-submarine/submarine/run_submarine_mnist_tony_rpc.sh
new file mode 100644
index 0000000000000000000000000000000000000000..602e9d8d494263b6f0afdc739596630f4167c3ad
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_submarine_mnist_tony_rpc.sh
@@ -0,0 +1,66 @@
+# 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.
+
+#!/usr/bin/env bash
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+DEBUG_PORT=8000
+if [ "$DEBUG" ]; then
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+while getopts 'd:' OPT; do
+ case $OPT in
+ d)
+ DATA_URL="$OPTARG";;
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [[ -n "$DATA_URL" ]]; then
+ WORKER_CMD="myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode --mnist_data_url ${DATA_URL}"
+else
+ WORKER_CMD="myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode"
+fi
+
+SUBMARINE_VERSION=${SUBMARINE_VER:-"0.5.0"}
+
+HADOOP_VERSION=2.9
+
+${JAVA_CMD} -cp /opt/submarine-dist-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar:/usr/local/hadoop/etc/hadoop:/opt/submarine-dist-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}/conf \
+ org.apache.submarine.client.cli.Cli job run --name tf-job-001 \
+ --framework tensorflow \
+ --verbose \
+ --input_path "" \
+ --num_workers 2 \
+ --worker_resources memory=1G,vcores=1 \
+ --num_ps 1 \
+ --ps_resources memory=1G,vcores=1 \
+ --worker_launch_cmd "${WORKER_CMD}" \
+ --ps_launch_cmd "myvenv.zip/venv/bin/python mnist_distributed.py --steps 2 --data_dir /tmp/data --working_dir /tmp/mode" \
+ --insecure \
+ --conf tony.containers.resources=/home/yarn/submarine/myvenv.zip#archive,/home/yarn/submarine/mnist_distributed.py,/opt/submarine-dist-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar
diff --git a/dev-support/mini-submarine/submarine/run_submarine_mxnet_cifar10_tony.sh b/dev-support/mini-submarine/submarine/run_submarine_mxnet_cifar10_tony.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4dec8687e9c6340f401c8a138a0475f24635bdcc
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_submarine_mxnet_cifar10_tony.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# 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.
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ if [ -n "$2" ]; then
+ DEBUG_PORT=$2
+ shift
+ fi
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+if [ "$DEBUG" ]; then
+ if [ -z "$DEBUG_PORT" ]; then
+ DEBUG_PORT=8000
+ fi
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+SUBMARINE_VERSION=0.5.0
+HADOOP_VERSION=2.9
+SUBMARINE_PATH=/opt/submarine-current
+HADOOP_CONF_PATH=/usr/local/hadoop/etc/hadoop
+
+${JAVA_CMD} -cp ${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar:${HADOOP_CONF_PATH} \
+ org.apache.submarine.client.cli.Cli job run \
+ --name mx-job-001 \
+ --framework mxnet \
+ --input_path "" \
+ --num_ps 1 \
+ --ps_resources memory=1G,vcores=1 \
+ --ps_launch_cmd "myvenv.zip/venv/bin/python image_classification.py --dataset cifar10 --model vgg11 --epochs 1 --kvstore dist_sync" \
+ --num_workers 2 \
+ --worker_resources memory=2G,vcores=1 \
+ --worker_launch_cmd "myvenv.zip/venv/bin/python image_classification.py --dataset cifar10 --model vgg11 --epochs 1 --kvstore dist_sync" \
+ --num_schedulers 1 \
+ --scheduler_resources memory=1G,vcores=1 \
+ --scheduler_launch_cmd "myvenv.zip/venv/bin/python image_classification.py --dataset cifar10 --model vgg11 --epochs 1 --kvstore dist_sync" \
+ --insecure \
+ --verbose \
+ --conf tony.containers.resources=/home/yarn/submarine/myvenv.zip#archive,/home/yarn/submarine/image_classification.py,${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar
diff --git a/dev-support/mini-submarine/submarine/run_submarine_pytorch_mnist_tony.sh b/dev-support/mini-submarine/submarine/run_submarine_pytorch_mnist_tony.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b57dd566971781e32b15c19c88ed102423dae001
--- /dev/null
+++ b/dev-support/mini-submarine/submarine/run_submarine_pytorch_mnist_tony.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+# 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.
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --debug*)
+ DEBUG=$1
+ if [ -n "$2" ]; then
+ DEBUG_PORT=$2
+ shift
+ fi
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+if [ "$DEBUG" ]; then
+ if [ -z "$DEBUG_PORT" ]; then
+ DEBUG_PORT=8000
+ fi
+ JAVA_CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${DEBUG_PORT}"
+else
+ JAVA_CMD="java"
+fi
+
+SUBMARINE_VERSION=0.5.0
+HADOOP_VERSION=2.9
+SUBMARINE_PATH=/opt/submarine-current
+HADOOP_CONF_PATH=/usr/local/hadoop/etc/hadoop
+MNIST_PATH=/home/yarn/submarine
+
+${JAVA_CMD} -cp ${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar:${HADOOP_CONF_PATH} \
+ org.apache.submarine.client.cli.Cli job run \
+ --name pytorch-job-001 \
+ --framework pytorch \
+ --input_path "" \
+ --num_workers 2 \
+ --worker_resources memory=1G,vcores=1 \
+ --worker_launch_cmd "myvenv.zip/venv/bin/python pytorch_mnist_distributed.py" \
+ --insecure \
+ --verbose \
+ --conf tony.containers.resources=${MNIST_PATH}/myvenv.zip#archive,${MNIST_PATH}/pytorch_mnist_distributed.py,${SUBMARINE_PATH}/submarine-all-${SUBMARINE_VERSION}-hadoop-${HADOOP_VERSION}.jar
diff --git a/dev-support/pysubmarine/Dockerfile b/dev-support/pysubmarine/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..90878f43811dde17ea0bc0f2eb6d027dc86d334b
--- /dev/null
+++ b/dev-support/pysubmarine/Dockerfile
@@ -0,0 +1,53 @@
+# 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.
+
+FROM ubuntu:18.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends apt-utils
+# Install JAVA
+RUN apt-get -q update \
+ && apt-get -q install -y --no-install-recommends openjdk-8-jdk libbcprov-java \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Docker
+RUN apt-get update && \
+ apt-get -y install apt-transport-https ca-certificates curl software-properties-common && \
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
+ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
+ apt-get update && \
+ apt-get -y install docker-ce
+# So no need to mount host's /var/run/docker.sock, dockerd will create in local fs
+VOLUME /var/lib/docker
+VOLUME /var/lib/docker.sock
+
+ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
+ENV JRE_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
+
+# Install user tools
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ git make libgtest-dev cmake wget unzip libtinfo-dev libz-dev \
+ libcurl4-openssl-dev libopenblas-dev g++ sudo \
+ apt-transport-https curl vim ca-certificates maven
+
+WORKDIR /root
+
+# Intstall conda
+ADD install-conda.sh /usr/local
+ADD bootstrap.sh /usr/local
+RUN chmod 755 /usr/local/install-conda.sh && \
+ bash /usr/local/install-conda.sh
+
+WORKDIR /workspace
diff --git a/dev-support/pysubmarine/bootstrap.sh b/dev-support/pysubmarine/bootstrap.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d4e310544143d6dfbfdba922d5ce0f2ad5371665
--- /dev/null
+++ b/dev-support/pysubmarine/bootstrap.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# 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.
+
+
+set -euo pipefail
+
+COMMAND=("$@")
+
+getent group "${CI_BUILD_GID}" || addgroup --gid "${CI_BUILD_GID}" "${CI_BUILD_GROUP}"
+getent passwd "${CI_BUILD_UID}" || adduser --gid "${CI_BUILD_GID}" --uid "${CI_BUILD_UID}" \
+ --gecos "${CI_BUILD_USER} (generated by with_the_same_user script)" \
+ --disabled-password --home "${CI_BUILD_HOME}" --quiet "${CI_BUILD_USER}"
+usermod -a -G sudo "${CI_BUILD_USER}"
+echo "${CI_BUILD_USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-nopasswd-sudo
+# shellcheck disable=SC2024
+sudo nohup dockerd --host=unix:///var/run/docker.sock > /var/log/dockerd.log 2>&1 &
+sudo usermod -aG docker "${CI_BUILD_USER}"
+
+sudo -u "#${CI_BUILD_UID}" --preserve-env \
+HOME="${CI_BUILD_HOME}" \
+PATH="${PATH}" \
+PYTHONPATH="${PYTHONPATH}" \
+"${COMMAND[@]}"
diff --git a/dev-support/pysubmarine/gen-sdk.sh b/dev-support/pysubmarine/gen-sdk.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b83eab1b7102a848fd4d95929b254e613121040a
--- /dev/null
+++ b/dev-support/pysubmarine/gen-sdk.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+# 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.
+
+FWDIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$FWDIR"
+
+SUBMARINE_PROJECT_PATH="$FWDIR/../.."
+SWAGGER_JAR_URL="https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/4.3.1/openapi-generator-cli-4.3.1.jar"
+SWAGGER_CODEGEN_JAR="openapi-generator-cli.jar"
+SWAGGER_CODEGEN_CONF="swagger_config.json"
+SWAGGER_CODEGEN_FILE="openapi.json"
+SDK_OUTPUT_PATH="sdk/python"
+
+submarine_dist_exists=$(find -L "${SUBMARINE_PROJECT_PATH}/submarine-dist/target" -name "submarine-dist-*.tar.gz")
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_dist_exists}" ]]; then
+ cd "${SUBMARINE_PROJECT_PATH}"
+ mvn clean package -DskipTests
+ cd "$FWDIR" # go back to FWDIR after packaging
+fi
+
+echo "Generating openAPI 3.0 definition file ..."
+# TODO(pingsutw): generate openapi.json without starting submarine server
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh start getMysqlJar
+sleep 5
+rm openapi.json
+wget http://localhost:8080/v1/openapi.json
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh stop
+
+openapi_generator_cli_exists=$(find -L "${FWDIR}" -name "openapi-generator-cli*")
+if [[ -z "${openapi_generator_cli_exists}" ]]; then
+ echo "Downloading the swagger-codegen JAR package ..."
+ wget -O "${SWAGGER_CODEGEN_JAR}" "${SWAGGER_JAR_URL}"
+fi
+
+echo "Generating Python SDK for Submarine ..."
+rm -r sdk/
+java -jar ${SWAGGER_CODEGEN_JAR} generate \
+ -i "${SWAGGER_CODEGEN_FILE}" \
+ -g python \
+ -o ${SDK_OUTPUT_PATH} \
+ -c ${SWAGGER_CODEGEN_CONF}
+
+echo "Insert apache license at the top of file ..."
+for filename in $(find ${SDK_OUTPUT_PATH}/submarine/experiment -type f); do
+ echo "$filename"
+ sed -i -e '1 e cat license-header.txt' "$filename"
+done
+
+echo "Move Experiment API to pysubmarine"
+cp -r sdk/python/submarine/experiment ${SUBMARINE_PROJECT_PATH}/submarine-sdk/pysubmarine/submarine/
+
+echo "Fix Python SDK code style"
+${SUBMARINE_PROJECT_PATH}/submarine-sdk/pysubmarine/github-actions/auto-format.sh
diff --git a/dev-support/pysubmarine/gen-ts-sdk.sh b/dev-support/pysubmarine/gen-ts-sdk.sh
new file mode 100755
index 0000000000000000000000000000000000000000..96c5437f8edb72df14bc25ebf3851848e415743a
--- /dev/null
+++ b/dev-support/pysubmarine/gen-ts-sdk.sh
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+# 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.
+
+FWDIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$FWDIR"
+
+SUBMARINE_PROJECT_PATH="$FWDIR/../.."
+SWAGGER_JAR_URL="https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/4.3.1/openapi-generator-cli-4.3.1.jar"
+SWAGGER_CODEGEN_JAR="openapi-generator-cli.jar"
+SWAGGER_CODEGEN_CONF="swagger_config.json"
+SWAGGER_CODEGEN_FILE="openapi.json"
+SDK_OUTPUT_PATH="sdk/typescript-angular"
+
+submarine_dist_exists=$(find -L "${SUBMARINE_PROJECT_PATH}/submarine-dist/target" -name "submarine-dist-*.tar.gz")
+# Build source code if the package doesn't exist.
+if [[ -z "${submarine_dist_exists}" ]]; then
+ cd "${SUBMARINE_PROJECT_PATH}"
+ mvn clean package -DskipTests
+ cd "$FWDIR" # go back to FWDIR after packaging
+fi
+
+echo "Generating openAPI 3.0 definition file ..."
+# TODO(pingsutw): generate openapi.json without starting submarine server
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh start getMysqlJar
+sleep 5
+rm openapi.json
+wget http://localhost:8080/v1/openapi.json
+bash ${SUBMARINE_PROJECT_PATH}/submarine-dist/target//submarine-dist-*/submarine-dist-*/bin/submarine-daemon.sh stop
+
+openapi_generator_cli_exists=$(find -L "${FWDIR}" -name "openapi-generator-cli*")
+if [[ -z "${openapi_generator_cli_exists}" ]]; then
+ echo "Downloading the swagger-codegen JAR package ..."
+ wget -O "${SWAGGER_CODEGEN_JAR}" "${SWAGGER_JAR_URL}"
+fi
+
+echo "Generating typescript-angular SDK for Submarine ..."
+rm -r sdk/
+java -jar ${SWAGGER_CODEGEN_JAR} generate \
+ -i "${SWAGGER_CODEGEN_FILE}" \
+ -g typescript-angular \
+ -o ${SDK_OUTPUT_PATH} \
+ -c ${SWAGGER_CODEGEN_CONF}
diff --git a/dev-support/pysubmarine/install-conda.sh b/dev-support/pysubmarine/install-conda.sh
new file mode 100644
index 0000000000000000000000000000000000000000..be6a7cd4e14e73510011d12bd33f25b773e6da37
--- /dev/null
+++ b/dev-support/pysubmarine/install-conda.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euo pipefail
+set -x
+
+wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh -O "$HOME"/anaconda.sh;
+bash "$HOME"/anaconda.sh -b -p /usr/bin/anaconda
+export PATH="/usr/bin/anaconda/bin:$PATH"
+cd "$HOME"
+# Useful for debugging any issues with conda
+conda info -a
+if [[ -n "${PYTHON_VERSION:-}" ]]; then
+ conda create -q -n submarine-dev python="$PYTHON_VERSION"
+else
+ conda create -q -n submarine-dev python=3.6
+fi
+
+source activate submarine-dev
+python --version
+pip install --upgrade pip
+
+# Install pysubmarine
+git clone https://github.com/apache/submarine.git
+cd submarine/submarine-sdk/pysubmarine
+pip install .
+pip install -r github-actions/lint-requirements.txt
+pip install -r github-actions/test-requirements.txt
diff --git a/dev-support/pysubmarine/license-header.txt b/dev-support/pysubmarine/license-header.txt
new file mode 100644
index 0000000000000000000000000000000000000000..09697dce6e11859e38a9bfb321bfc72eb88b8ce6
--- /dev/null
+++ b/dev-support/pysubmarine/license-header.txt
@@ -0,0 +1,15 @@
+# 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.
+
diff --git a/dev-support/pysubmarine/openapi.json b/dev-support/pysubmarine/openapi.json
new file mode 100644
index 0000000000000000000000000000000000000000..9ab79b23ff87606310b5aaac3271e0ad7a0d0d7a
--- /dev/null
+++ b/dev-support/pysubmarine/openapi.json
@@ -0,0 +1,409 @@
+{
+ "openapi" : "3.0.1",
+ "info" : {
+ "title" : "Submarine Experiment API",
+ "description" : "The Submarine REST API allows you to create, list, and get experiments. The\nAPI is hosted under the /v1/experiment route on the Submarine server. For example,\nto list experiments on a server hosted at http://localhost:8080, access\nhttp://localhost:8080/api/v1/experiment/",
+ "termsOfService" : "http://swagger.io/terms/",
+ "contact" : {
+ "email" : "dev@submarine.apache.org"
+ },
+ "license" : {
+ "name" : "Apache 2.0",
+ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "version" : "0.5.0"
+ },
+ "servers" : [ {
+ "url" : "/api"
+ } ],
+ "paths" : {
+ "/v1/experiment/{id}" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Get the experiment's detailed info by id",
+ "operationId" : "getExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ },
+ "delete" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Delete the experiment",
+ "operationId" : "deleteExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ },
+ "patch" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Update the experiment in the submarine server with spec",
+ "operationId" : "patchExperiment",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "requestBody" : {
+ "content" : {
+ "application/yaml" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ },
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ }
+ },
+ "/v1/experiment/logs" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "List experiment's log",
+ "operationId" : "listLog",
+ "parameters" : [ {
+ "name" : "status",
+ "in" : "query",
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/experiment" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "List experiments",
+ "operationId" : "listExperiments",
+ "parameters" : [ {
+ "name" : "status",
+ "in" : "query",
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Create an experiment",
+ "operationId" : "createExperiment",
+ "requestBody" : {
+ "content" : {
+ "application/yaml" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ },
+ "application/json" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/ExperimentSpec"
+ }
+ }
+ }
+ },
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/experiment/logs/{id}" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Log experiment by id",
+ "operationId" : "getLog",
+ "parameters" : [ {
+ "name" : "id",
+ "in" : "path",
+ "required" : true,
+ "schema" : {
+ "type" : "string"
+ }
+ } ],
+ "responses" : {
+ "default" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "$ref" : "#/components/schemas/JsonResponse"
+ }
+ }
+ }
+ },
+ "404" : {
+ "description" : "Experiment not found"
+ }
+ }
+ }
+ },
+ "/v1/experiment/ping" : {
+ "get" : {
+ "tags" : [ "experiment" ],
+ "summary" : "Ping submarine server",
+ "description" : "Return the Pong message for test the connectivity",
+ "operationId" : "ping",
+ "responses" : {
+ "200" : {
+ "description" : "successful operation",
+ "content" : {
+ "application/json; charset=utf-8" : {
+ "schema" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components" : {
+ "schemas" : {
+ "JsonResponse" : {
+ "type" : "object",
+ "properties" : {
+ "code" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "success" : {
+ "type" : "boolean"
+ },
+ "result" : {
+ "type" : "object"
+ },
+ "attributes" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "object"
+ }
+ }
+ }
+ },
+ "CodeSpec" : {
+ "type" : "object",
+ "properties" : {
+ "syncMode" : {
+ "type" : "string"
+ },
+ "url" : {
+ "type" : "string"
+ }
+ }
+ },
+ "EnvironmentSpec" : {
+ "type" : "object",
+ "properties" : {
+ "name" : {
+ "type" : "string"
+ },
+ "dockerImage" : {
+ "type" : "string"
+ },
+ "kernelSpec" : {
+ "$ref" : "#/components/schemas/KernelSpec"
+ },
+ "description" : {
+ "type" : "string"
+ },
+ "image" : {
+ "type" : "string"
+ }
+ }
+ },
+ "ExperimentMeta" : {
+ "type" : "object",
+ "properties" : {
+ "name" : {
+ "type" : "string"
+ },
+ "namespace" : {
+ "type" : "string"
+ },
+ "framework" : {
+ "type" : "string"
+ },
+ "cmd" : {
+ "type" : "string"
+ },
+ "envVars" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ }
+ }
+ },
+ "ExperimentSpec" : {
+ "type" : "object",
+ "properties" : {
+ "meta" : {
+ "$ref" : "#/components/schemas/ExperimentMeta"
+ },
+ "environment" : {
+ "$ref" : "#/components/schemas/EnvironmentSpec"
+ },
+ "spec" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "$ref" : "#/components/schemas/ExperimentTaskSpec"
+ }
+ },
+ "code" : {
+ "$ref" : "#/components/schemas/CodeSpec"
+ }
+ }
+ },
+ "ExperimentTaskSpec" : {
+ "type" : "object",
+ "properties" : {
+ "replicas" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "resources" : {
+ "type" : "string"
+ },
+ "name" : {
+ "type" : "string"
+ },
+ "image" : {
+ "type" : "string"
+ },
+ "cmd" : {
+ "type" : "string"
+ },
+ "envVars" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ },
+ "cpu" : {
+ "type" : "string"
+ },
+ "gpu" : {
+ "type" : "string"
+ },
+ "memory" : {
+ "type" : "string"
+ }
+ }
+ },
+ "KernelSpec" : {
+ "type" : "object",
+ "properties" : {
+ "name" : {
+ "type" : "string"
+ },
+ "channels" : {
+ "type" : "array",
+ "items" : {
+ "type" : "string"
+ }
+ },
+ "dependencies" : {
+ "type" : "array",
+ "items" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/dev-support/pysubmarine/run-pysubmarine-ci.sh b/dev-support/pysubmarine/run-pysubmarine-ci.sh
new file mode 100755
index 0000000000000000000000000000000000000000..317e49154922752d9cb761450bdc38ecadc18704
--- /dev/null
+++ b/dev-support/pysubmarine/run-pysubmarine-ci.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+# 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.
+
+FWDIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$FWDIR"
+
+# shellcheck disable=SC2034
+SUBMARINE_PROJECT_PATH="$FWDIR/../.."
+
+# build image
+echo "Start building the mini-submarine docker image..."
+docker build --tag pysubmarine-ci .
+
+docker run --rm --pid=host \
+ --privileged \
+ -v "$SUBMARINE_PROJECT_PATH":/workspace \
+ -e "CI_BUILD_HOME=/" \
+ -e "CI_BUILD_USER=$(id -u -n)" \
+ -e "CI_BUILD_UID=$(id -u)" \
+ -e "CI_BUILD_GROUP=$(id -g -n)" \
+ -e "CI_BUILD_GID=$(id -g)" \
+ -e "PATH=/usr/bin/anaconda/envs/submarine-dev/bin:${PATH}" \
+ -e "PYTHONPATH=python:/usr/bin/anaconda/envs/submarine-dev/bin/python"\
+ -it pysubmarine-ci \
+ /bin/bash --login /usr/local/bootstrap.sh bash
diff --git a/dev-support/pysubmarine/swagger_config.json b/dev-support/pysubmarine/swagger_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..d7e0772f1a7e1c20092fba94c29f581da28923cc
--- /dev/null
+++ b/dev-support/pysubmarine/swagger_config.json
@@ -0,0 +1,5 @@
+{
+ "packageName" : "submarine.experiment",
+ "projectName" : "submarine.experiment",
+ "packageVersion": "0.5.0"
+}
diff --git a/dev-support/style-check/lint-angular.sh b/dev-support/style-check/lint-angular.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e6af29b872ad0fb377fb757727454f674abc1c55
--- /dev/null
+++ b/dev-support/style-check/lint-angular.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+npm install prettier@^2.0.5
+
+WORKBENCH_NG=./submarine-workbench/workbench-web
+
+PRETTIER_ERRORS=$(./node_modules/.bin/prettier --check --trailing-comma none "$WORKBENCH_NG/src/**/*.{ts,html}" | grep "Forgot to run Prettier?")
+
+
+if test "$PRETTIER_ERRORS"; then
+ echo -e "prettier checks failed at following occurrences:\n$PRETTIER_ERRORS\n"
+ echo -e "Please use \\033[31m"./node_modules/.bin/prettier --write --trailing-comma none "$WORKBENCH_NG/src/**/*.{ts,html}""\\033[0m to format code automatically\n"
+ exit 1
+else
+ echo -e "Checkstyle checks passed."
+fi
+
diff --git a/dev-support/style-check/lint-java.sh b/dev-support/style-check/lint-java.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6b1dea67f2dc12fd124f0094bde1737fd026fbf3
--- /dev/null
+++ b/dev-support/style-check/lint-java.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+export MAVEN_OPTS="-Xmx2g -XX:ReservedCodeCacheSize=512m -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN"
+mvn --no-transfer-progress install -DskipTests -pl "!org.apache.submarine:submarine-cloud"
+
+ERRORS=$(mvn checkstyle:check | grep ERROR)
+
+if test ! -z "$ERRORS"; then
+ echo -e "Checkstyle checks failed at following occurrences:\n$ERRORS"
+ find . -name checkstyle-output.xml | xargs cat | grep -v checkstyle | grep -v "
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The binary distribution of this product bundles binaries of leveldbjni
+(https://github.com/fusesource/leveldbjni), which is available under the
+following license:
+
+Copyright (c) 2011 FuseSource Corp. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of FuseSource Corp. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+For hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/{fstatat|openat|unlinkat}.h:
+
+Copyright (c) 2012 The FreeBSD Foundation
+All rights reserved.
+
+This software was developed by Pawel Jakub Dawidek under sponsorship from
+the FreeBSD Foundation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+=============
+
+The binary distribution of this product bundles binaries of leveldb
+(http://code.google.com/p/leveldb/), which is available under the following
+license:
+
+Copyright (c) 2011 The LevelDB Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The binary distribution of this product bundles binaries of snappy
+(http://code.google.com/p/snappy/), which is available under the following
+license:
+
+Copyright 2011, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/dataTables.bootstrap.js
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/dataTables.bootstrap.css
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/jquery.dataTables.min.js
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.10.18/
+--------------------------------------------------------------------------------
+Copyright (C) 2008-2016, SpryMedia Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/dust-full-2.0.0.min.js
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/dust-helpers-1.1.1.min.js
+--------------------------------------------------------------------------------
+
+Copyright (c) 2010 Aleksander Williams
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/moment.min.js
+--------------------------------------------------------------------------------
+
+Copyright (c) 2011-2016 Tim Wood, Iskren Chernev, Moment.js contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/bootstrap-3.3.7
+hadoop-tools/hadoop-sls/src/main/html/js/thirdparty/bootstrap.min.js
+hadoop-tools/hadoop-sls/src/main/html/css/bootstrap.min.css
+hadoop-tools/hadoop-sls/src/main/html/css/bootstrap-responsive.min.css
+bootstrap v3.3.6
+broccoli-asset-rev v2.4.2
+broccoli-funnel v1.0.1
+datatables v1.10.8
+em-helpers v0.5.13
+em-table v0.1.6
+ember v2.2.0
+ember-array-contains-helper v1.0.2
+ember-bootstrap v0.5.1
+ember-cli v1.13.13
+ember-cli-app-version v1.0.0
+ember-cli-babel v5.1.6
+ember-cli-content-security-policy v0.4.0
+ember-cli-dependency-checker v1.2.0
+ember-cli-htmlbars v1.0.2
+ember-cli-htmlbars-inline-precompile v0.3.1
+ember-cli-ic-ajax v0.2.1
+ember-cli-inject-live-reload v1.4.0
+ember-cli-jquery-ui v0.0.20
+ember-cli-qunit v1.2.1
+ember-cli-release v0.2.8
+ember-cli-shims v0.0.6
+ember-cli-sri v1.2.1
+ember-cli-test-loader v0.2.1
+ember-cli-uglify v1.2.0
+ember-d3 v0.1.0
+ember-data v2.1.0
+ember-disable-proxy-controllers v1.0.1
+ember-export-application-global v1.0.5
+ember-load-initializers v0.1.7
+ember-qunit v0.4.16
+ember-qunit-notifications v0.1.0
+ember-resolver v2.0.3
+ember-spin-spinner v0.2.3
+ember-truth-helpers v1.2.0
+jquery v2.1.4
+jquery-ui v1.11.4
+loader.js v3.3.0
+momentjs v2.10.6
+qunit v1.19.0
+select2 v4.0.0
+snippet-ss v1.11.0
+spin.js v2.3.2
+Azure Data Lake Store - Java client SDK 2.0.11
+JCodings 1.0.8
+Joni 2.1.2
+Mockito 1.8.5
+JUL to SLF4J bridge 1.7.25
+SLF4J API Module 1.7.25
+SLF4J LOG4J-12 Binding 1.7.25
+--------------------------------------------------------------------------------
+
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+For:
+./hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/nvd3-1.8.5.* (css and js files)
+--------------------------------------------------------------------------------
+Copyright (c) 2011-2014 Novus Partners, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software distributed under the
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ express or implied. See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/angular-nvd3-1.0.9.min.js
+--------------------------------------------------------------------------------
+The MIT License (MIT)
+Copyright (c) 2014 Konstantin Skipor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+and associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/angular-1.6.4.min.js
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/angular-route-1.6.4.min.js
+--------------------------------------------------------------------------------
+The MIT License
+
+Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+
+
+For:
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/jquery-3.3.1.min.js
+hadoop-tools/hadoop-sls/src/main/html/js/thirdparty/jquery.js
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery
+Apache HBase - Server which contains JQuery minified javascript library version 1.8.3
+Microsoft JDBC Driver for SQLServer - version 6.2.1.jre7
+--------------------------------------------------------------------------------
+
+MIT License
+
+Copyright (c) 2003-2017 Optimatika
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+For:
+oj! Algorithms - version 43.0
+--------------------------------------------------------------------------------
+
+Copyright 2005, 2012, 2013 jQuery Foundation and other contributors, https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/jquery/jquery
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+All files located in the node_modules and external directories are
+externally maintained libraries used by this software which have their
+own licenses; we recommend you read them, as their terms may differ from
+the terms above.
+
+For:
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jt/jquery.jstree.js
+--------------------------------------------------------------------------------
+
+Copyright (c) 2014 Ivan Bozhanov
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For:
+hadoop-tools/hadoop-sls/src/main/html/js/thirdparty/d3.v3.js
+hadoop-hdfs-project/hadoop-hdfs/src/main/webapps/static/d3-3.5.17.min.js
+--------------------------------------------------------------------------------
+
+D3 is available under a 3-clause BSD license. For details, see:
+hadoop-tools/hadoop-sls/src/main/html/js/thirdparty/d3-LICENSE
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+HSQLDB Database 2.3.4
+--------------------------------------------------------------------------------
+(HSQL License)
+"COPYRIGHTS AND LICENSES (based on BSD License)
+
+For work developed by the HSQL Development Group:
+
+Copyright (c) 2001-2016, The HSQL Development Group
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the name of the HSQL Development Group nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+For work originally developed by the Hypersonic SQL Group:
+
+Copyright (c) 1995-2000 by the Hypersonic SQL Group.
+All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the name of the Hypersonic SQL Group nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This software consists of voluntary contributions made by many individuals on behalf of the
+Hypersonic SQL Group."
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+Java Servlet API 3.1.0
+servlet-api 2.5
+jsp-api 2.1
+jsr311-api 1.1.1
+Glassfish Jasper 6.1.14
+Servlet Specification 2.5 API 6.1.14
+--------------------------------------------------------------------------------
+(CDDL 1.0)
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+1. Definitions.
+
+1.1. Contributor means each individual or entity
+that creates or contributes to the creation of
+Modifications.
+
+1.2. Contributor Version means the combination of the
+Original Software, prior Modifications used by a Contributor (if any), and the
+Modifications made by that particular Contributor.
+
+1.3. Covered
+Software means (a) the Original Software, or (b) Modifications, or (c) the
+combination of files containing Original Software with files containing
+Modifications, in each case including portions
+thereof.
+
+1.4. Executable means the Covered Software in any form other
+than Source Code.
+
+1.5. Initial Developer means the individual or entity
+that first makes Original Software available under this
+License.
+
+1.6. Larger Work means a work which combines Covered Software or
+portions thereof with code not governed by the terms of this
+License.
+
+1.7. License means this document.
+
+1.8. Licensable means
+having the right to grant, to the maximum extent possible, whether at the time
+of the initial grant or subsequently acquired, any and all of the rights
+conveyed herein.
+
+1.9. Modifications means the Source Code and Executable
+form of any of the following:
+A. Any file that results from an addition to,
+deletion from or modification of the contents of a file containing Original
+Software or previous Modifications;
+B. Any new file that contains any part of the Original Software
+or previous Modification; or
+C. Any new file that is contributed or otherwise made available
+under the terms of this License.
+
+1.10. Original Software means the Source Code and Executable form of
+computer software code that is originally released under this License.
+
+1.11. Patent Claims means any patent claim(s), now owned or
+hereafter acquired, including without limitation, method, process, and apparatus
+claims, in any patent Licensable by grantor.
+
+1.12. Source Code means (a) the common form of computer software code in which
+modifications are made and (b) associated documentation included in or
+with such code.
+
+1.13. You (or Your) means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal entities,
+You includes any entity which controls, is controlled by, or is under common control
+with You. For purposes of this definition, control means (a) the power, direct
+or indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (b) ownership of more than fifty percent (50%) of the
+outstanding shares or beneficial ownership of such entity.
+
+2. License Grants.
+
+2.1. The Initial Developer Grant. Conditioned upon Your compliance
+with Section 3.1 below and subject to third party intellectual property claims,
+the Initial Developer hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than
+patent or trademark) Licensable by Initial Developer, to use, reproduce, modify,
+display, perform, sublicense and distribute the Original Software (or portions
+thereof), with or without Modifications, and/or as part of a Larger Work;
+and
+
+(b) under Patent Claims infringed by the making, using or selling of
+Original Software, to make, have made, use, practice, sell, and offer for sale,
+and/or otherwise dispose of the Original Software (or portions
+thereof);
+
+(c) The licenses granted in Sections 2.1(a) and (b) are
+effective on the date Initial Developer first distributes or otherwise makes the
+Original Software available to a third party under the terms of this
+License;
+
+(d) Notwithstanding Section 2.1(b) above, no patent license is
+granted: (1) for code that You delete from the Original Software, or (2) for
+infringements caused by: (i) the modification of the Original Software, or
+(ii) the combination of the Original Software with other software or
+devices.
+
+2.2. Contributor Grant. Conditioned upon Your compliance with
+Section 3.1 below and subject to third party intellectual property claims, each
+Contributor hereby grants You a world-wide, royalty-free, non-exclusive
+license:
+
+(a) under intellectual property rights (other than patent or
+trademark) Licensable by Contributor to use, reproduce, modify, display,
+perform, sublicense and distribute the Modifications created by such Contributor
+(or portions thereof), either on an unmodified basis, with other Modifications,
+as Covered Software and/or as part of a Larger Work; and
+
+(b) under Patent
+Claims infringed by the making, using, or selling of Modifications made by that
+Contributor either alone and/or in combination with its Contributor Version (or
+portions of such combination), to make, use, sell, offer for sale, have made,
+and/or otherwise dispose of: (1) Modifications made by that Contributor (or
+portions thereof); and (2) the combination of Modifications made by that
+Contributor with its Contributor Version (or portions of such
+combination).
+
+(c) The licenses granted in Sections 2.2(a) and 2.2(b) are
+effective on the date Contributor first distributes or otherwise makes the
+Modifications available to a third party.
+
+(d) Notwithstanding Section 2.2(b)
+above, no patent license is granted: (1) for any code that Contributor has
+deleted from the Contributor Version; (2) for infringements caused by:
+(i) third party modifications of Contributor Version, or (ii) the combination
+of Modifications made by that Contributor with other software (except as part of
+the Contributor Version) or other devices; or (3) under Patent Claims infringed
+by Covered Software in the absence of Modifications made by that
+Contributor.
+
+3. Distribution Obligations.
+
+3.1. Availability of Source
+Code. Any Covered Software that You distribute or otherwise make available in
+Executable form must also be made available in Source Code form and that Source
+Code form must be distributed only under the terms of this License. You must
+include a copy of this License with every copy of the Source Code form of the
+Covered Software You distribute or otherwise make available. You must inform
+recipients of any such Covered Software in Executable form as to how they can
+obtain such Covered Software in Source Code form in a reasonable manner on or
+through a medium customarily used for software exchange.
+
+3.2.
+Modifications. The Modifications that You create or to which You contribute are
+governed by the terms of this License. You represent that You believe Your
+Modifications are Your original creation(s) and/or You have sufficient rights to
+grant the rights conveyed by this License.
+
+3.3. Required Notices. You must
+include a notice in each of Your Modifications that identifies You as the
+Contributor of the Modification. You may not remove or alter any copyright,
+patent or trademark notices contained within the Covered Software, or any
+notices of licensing or any descriptive text giving attribution to any
+Contributor or the Initial Developer.
+
+3.4. Application of Additional Terms.
+You may not offer or impose any terms on any Covered Software in Source Code
+form that alters or restricts the applicable version of this License or the
+recipients rights hereunder. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations to one or more recipients
+of Covered Software. However, you may do so only on Your own behalf, and not on
+behalf of the Initial Developer or any Contributor. You must make it absolutely
+clear that any such warranty, support, indemnity or liability obligation is
+offered by You alone, and You hereby agree to indemnify the Initial Developer
+and every Contributor for any liability incurred by the Initial Developer or
+such Contributor as a result of warranty, support, indemnity or liability terms
+You offer.
+
+3.5. Distribution of Executable Versions. You may distribute the
+Executable form of the Covered Software under the terms of this License or under
+the terms of a license of Your choice, which may contain terms different from
+this License, provided that You are in compliance with the terms of this License
+and that the license for the Executable form does not attempt to limit or alter
+the recipients rights in the Source Code form from the rights set forth in this
+License. If You distribute the Covered Software in Executable form under a
+different license, You must make it absolutely clear that any terms which differ
+from this License are offered by You alone, not by the Initial Developer or
+Contributor. You hereby agree to indemnify the Initial Developer and every
+Contributor for any liability incurred by the Initial Developer or such
+Contributor as a result of any such terms You offer.
+
+3.6. Larger Works. You
+may create a Larger Work by combining Covered Software with other code not
+governed by the terms of this License and distribute the Larger Work as a single
+product. In such a case, You must make sure the requirements of this License are
+fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+4.1.
+New Versions. Sun Microsystems, Inc. is the initial license steward and may
+publish revised and/or new versions of this License from time to time. Each
+version will be given a distinguishing version number. Except as provided in
+Section 4.3, no one other than the license steward has the right to modify this
+License.
+
+4.2. Effect of New Versions. You may always continue to use,
+distribute or otherwise make the Covered Software available under the terms of
+the version of the License under which You originally received the Covered
+Software. If the Initial Developer includes a notice in the Original Software
+prohibiting it from being distributed or otherwise made available under any
+subsequent version of the License, You must distribute and make the Covered
+Software available under the terms of the version of the License under which You
+originally received the Covered Software. Otherwise, You may also choose to use,
+distribute or otherwise make the Covered Software available under the terms of
+any subsequent version of the License published by the license
+steward.
+
+4.3. Modified Versions. When You are an Initial Developer and You
+want to create a new license for Your Original Software, You may create and use
+a modified version of this License if You: (a) rename the license and remove
+any references to the name of the license steward (except to note that the
+license differs from this License); and (b) otherwise make it clear that the
+license contains terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN AS IS BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS,
+MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER
+OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR
+CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
+LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+THIS DISCLAIMER.
+
+6. TERMINATION.
+
+6.1. This License and the rights
+granted hereunder will terminate automatically if You fail to comply with terms
+herein and fail to cure such breach within 30 days of becoming aware of the
+breach. Provisions which, by their nature, must remain in effect beyond the
+termination of this License shall survive.
+
+6.2. If You assert a patent
+infringement claim (excluding declaratory judgment actions) against Initial
+Developer or a Contributor (the Initial Developer or Contributor against whom
+You assert such claim is referred to as Participant) alleging that the
+Participant Software (meaning the Contributor Version where the Participant is a
+Contributor or the Original Software where the Participant is the Initial
+Developer) directly or indirectly infringes any patent, then any and all rights
+granted directly or indirectly to You by such Participant, the Initial Developer
+(if the Initial Developer is not the Participant) and all Contributors under
+Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from
+Participant terminate prospectively and automatically at the expiration of such
+60 day notice period, unless if within such 60 day period You withdraw Your
+claim with respect to the Participant Software against such Participant either
+unilaterally or pursuant to a written agreement with Participant.
+
+6.3. In
+the event of termination under Sections 6.1 or 6.2 above, all end user licenses
+that have been validly granted by You or any distributor hereunder prior to
+termination (excluding licenses granted to You by any distributor) shall survive
+termination.
+
+7. LIMITATION OF LIABILITY.
+UNDER NO CIRCUMSTANCES AND UNDER
+NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE,
+SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY
+PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF
+GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE
+POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO
+LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO
+THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT
+ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+The Covered Software is a commercial item, as that term is defined in
+48 C.F.R. 2.101 (Oct. 1995), consisting of commercial computer software (as
+that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and commercial computer
+software documentation as such terms are used in 48 C.F.R. 12.212 (Sept.
+1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through
+227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software
+with only those rights set forth herein. This U.S. Government Rights clause is
+in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision
+that addresses Government rights in computer software under this
+License.
+
+9. MISCELLANEOUS.
+This License represents the complete agreement
+concerning subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable. This License shall be governed by the law of the
+jurisdiction specified in a notice contained within the Original Software
+(except to the extent applicable law, if any, provides otherwise), excluding
+such jurisdictions conflict-of-law provisions. Any litigation relating to this
+License shall be subject to the jurisdiction of the courts located in the
+jurisdiction and venue specified in a notice contained within the Original
+Software, with the losing party responsible for costs, including, without
+limitation, court costs and reasonable attorneys fees and expenses. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any law or regulation which provides that
+the language of a contract shall be construed against the drafter shall not
+apply to this License. You agree that You alone are responsible for compliance
+with the United States export administration regulations (and the export control
+laws and regulation of any other countries) when You use, distribute or
+otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+As between Initial Developer and the Contributors, each party is
+responsible for claims and damages arising, directly or indirectly, out of its
+utilization of rights under this License and You agree to work with Initial
+Developer and Contributors to distribute such responsibility on an equitable
+basis. Nothing herein is intended or shall be deemed to constitute any admission
+of liability.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+jersey-client 1.19
+jersey-core 1.19
+jersey-grizzly2 1.19
+jersey-grizzly2-servlet 1.19
+jersey-json 1.19
+jersey-server 1.19
+jersey-servlet 1.19
+jersey-guice 1.19
+Jersey Test Framework - Grizzly 2 Module 1.19
+JAXB RI 2.2.3
+Java Architecture for XML Binding 2.2.11
+grizzly-framework 2.2.21
+grizzly-http 2.2.21
+grizzly-http-server 2.2.21
+grizzly-http-servlet 2.2.21
+grizzly-rcm 2.2.21
+JavaBeans Activation Framework 1.2.0
+--------------------------------------------------------------------------------
+(CDDL 1.1)
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1
+
+1. Definitions.
+
+1.1. “Contributor” means each individual or entity that creates or
+contributes to the creation of Modifications.
+1.2. “Contributor Version” means the combination of the Original Software,
+prior Modifications used by a Contributor (if any), and the Modifications made
+by that particular Contributor.
+1.3. “Covered Software” means (a) the Original Software, or (b)
+Modifications, or (c) the combination of files containing Original Software with
+files containing Modifications, in each case including portions thereof.
+1.4. “Executable” means the Covered Software in any form other than Source
+Code.
+1.5. “Initial Developer” means the individual or entity that first makes
+Original Software available under this License.
+1.6. “Larger Work” means a work which combines Covered Software or portions
+thereof with code not governed by the terms of this License.
+1.7. “License” means this document.
+1.8. “Licensable” means having the right to grant, to the maximum extent
+possible, whether at the time of the initial grant or subsequently acquired, any
+and all of the rights conveyed herein.
+1.9. “Modifications” means the Source Code and Executable form of any of the
+following:
+A. Any file that results from an addition to, deletion from or modification of
+the contents of a file containing Original Software or previous Modifications;
+B. Any new file that contains any part of the Original Software or previous
+Modification; or
+C. Any new file that is contributed or otherwise made available under the terms
+of this License.
+1.10. “Original Software” means the Source Code and Executable form of
+computer software code that is originally released under this License.
+1.11. “Patent Claims” means any patent claim(s), now owned or hereafter
+acquired, including without limitation, method, process, and apparatus claims,
+in any patent Licensable by grantor.
+1.12. “Source Code” means (a) the common form of computer software code in
+which modifications are made and (b) associated documentation included in or
+with such code.
+1.13. “You” (or “Your”) means an individual or a legal entity exercising
+rights under, and complying with all of the terms of, this License. For legal
+entities, “You” includes any entity which controls, is controlled by, or is
+under common control with You. For purposes of this definition, “control”
+means (a) the power, direct or indirect, to cause the direction or management of
+such entity, whether by contract or otherwise, or (b) ownership of more than
+fifty percent (50%) of the outstanding shares or beneficial ownership of such
+entity.
+
+2. License Grants.
+
+2.1. The Initial Developer Grant.
+
+Conditioned upon Your compliance with Section 3.1 below and subject to
+third party intellectual property claims, the Initial Developer hereby grants
+You a world-wide, royalty-free, non-exclusive license:
+(a) under intellectual
+property rights (other than patent or trademark) Licensable by Initial
+Developer, to use, reproduce, modify, display, perform, sublicense and
+distribute the Original Software (or portions thereof), with or without
+Modifications, and/or as part of a Larger Work; and
+(b) under Patent Claims
+infringed by the making, using or selling of Original Software, to make, have
+made, use, practice, sell, and offer for sale, and/or otherwise dispose of the
+Original Software (or portions thereof).
+(c) The licenses granted in Sections
+2.1(a) and (b) are effective on the date Initial Developer first distributes or
+otherwise makes the Original Software available to a third party under the terms
+of this License.
+(d) Notwithstanding Section 2.1(b) above, no patent license is
+granted: (1) for code that You delete from the Original Software, or (2) for
+infringements caused by: (i) the modification of the Original Software, or (ii)
+the combination of the Original Software with other software or devices.
+
+2.2. Contributor Grant.
+
+Conditioned upon Your compliance with Section 3.1 below and
+subject to third party intellectual property claims, each Contributor hereby
+grants You a world-wide, royalty-free, non-exclusive license:
+(a) under
+intellectual property rights (other than patent or trademark) Licensable by
+Contributor to use, reproduce, modify, display, perform, sublicense and
+distribute the Modifications created by such Contributor (or portions thereof),
+either on an unmodified basis, with other Modifications, as Covered Software
+and/or as part of a Larger Work; and
+(b) under Patent Claims infringed by the
+making, using, or selling of Modifications made by that Contributor either alone
+and/or in combination with its Contributor Version (or portions of such
+combination), to make, use, sell, offer for sale, have made, and/or otherwise
+dispose of: (1) Modifications made by that Contributor (or portions thereof);
+and (2) the combination of Modifications made by that Contributor with its
+Contributor Version (or portions of such combination).
+(c) The licenses granted
+in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first
+distributes or otherwise makes the Modifications available to a third
+party.
+(d) Notwithstanding Section 2.2(b) above, no patent license is granted:
+(1) for any code that Contributor has deleted from the Contributor Version; (2)
+for infringements caused by: (i) third party modifications of Contributor
+Version, or (ii) the combination of Modifications made by that Contributor with
+other software (except as part of the Contributor Version) or other devices; or
+(3) under Patent Claims infringed by Covered Software in the absence of
+Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+3.1. Availability of Source Code.
+Any Covered Software that You distribute or
+otherwise make available in Executable form must also be made available in
+Source Code form and that Source Code form must be distributed only under the
+terms of this License. You must include a copy of this License with every copy
+of the Source Code form of the Covered Software You distribute or otherwise make
+available. You must inform recipients of any such Covered Software in Executable
+form as to how they can obtain such Covered Software in Source Code form in a
+reasonable manner on or through a medium customarily used for software
+exchange.
+3.2. Modifications.
+The Modifications that You create or to which
+You contribute are governed by the terms of this License. You represent that You
+believe Your Modifications are Your original creation(s) and/or You have
+sufficient rights to grant the rights conveyed by this License.
+3.3. Required Notices.
+You must include a notice in each of Your Modifications that
+identifies You as the Contributor of the Modification. You may not remove or
+alter any copyright, patent or trademark notices contained within the Covered
+Software, or any notices of licensing or any descriptive text giving attribution
+to any Contributor or the Initial Developer.
+3.4. Application of Additional Terms.
+You may not offer or impose any terms on any Covered Software in Source
+Code form that alters or restricts the applicable version of this License or the
+recipients' rights hereunder. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations to one or more recipients
+of Covered Software. However, you may do so only on Your own behalf, and not on
+behalf of the Initial Developer or any Contributor. You must make it absolutely
+clear that any such warranty, support, indemnity or liability obligation is
+offered by You alone, and You hereby agree to indemnify the Initial Developer
+and every Contributor for any liability incurred by the Initial Developer or
+such Contributor as a result of warranty, support, indemnity or liability terms
+You offer.
+3.5. Distribution of Executable Versions.
+You may distribute the
+Executable form of the Covered Software under the terms of this License or under
+the terms of a license of Your choice, which may contain terms different from
+this License, provided that You are in compliance with the terms of this License
+and that the license for the Executable form does not attempt to limit or alter
+the recipient's rights in the Source Code form from the rights set forth in
+this License. If You distribute the Covered Software in Executable form under a
+different license, You must make it absolutely clear that any terms which differ
+from this License are offered by You alone, not by the Initial Developer or
+Contributor. You hereby agree to indemnify the Initial Developer and every
+Contributor for any liability incurred by the Initial Developer or such
+Contributor as a result of any such terms You offer.
+3.6. Larger Works.
+You
+may create a Larger Work by combining Covered Software with other code not
+governed by the terms of this License and distribute the Larger Work as a single
+product. In such a case, You must make sure the requirements of this License are
+fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+4.1. New Versions.
+Oracle is the initial license steward and may publish revised and/or
+new versions of this License from time to time. Each version will be given a
+distinguishing version number. Except as provided in Section 4.3, no one other
+than the license steward has the right to modify this License.
+4.2. Effect of New Versions.
+You may always continue to use, distribute or otherwise make the
+Covered Software available under the terms of the version of the License under
+which You originally received the Covered Software. If the Initial Developer
+includes a notice in the Original Software prohibiting it from being distributed
+or otherwise made available under any subsequent version of the License, You
+must distribute and make the Covered Software available under the terms of the
+version of the License under which You originally received the Covered Software.
+Otherwise, You may also choose to use, distribute or otherwise make the Covered
+Software available under the terms of any subsequent version of the License
+published by the license steward.
+4.3. Modified Versions.
+When You are an
+Initial Developer and You want to create a new license for Your Original
+Software, You may create and use a modified version of this License if You: (a)
+rename the license and remove any references to the name of the license steward
+(except to note that the license differs from this License); and (b) otherwise
+make it clear that the license contains terms which differ from this
+License.
+
+5. DISCLAIMER OF WARRANTY.
+
+COVERED SOFTWARE IS PROVIDED UNDER THIS
+LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE
+IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
+NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY
+RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED
+SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+6. TERMINATION.
+
+6.1. This License and the rights granted hereunder will
+terminate automatically if You fail to comply with terms herein and fail to cure
+such breach within 30 days of becoming aware of the breach. Provisions which, by
+their nature, must remain in effect beyond the termination of this License shall
+survive.
+6.2. If You assert a patent infringement claim (excluding declaratory
+judgment actions) against Initial Developer or a Contributor (the Initial
+Developer or Contributor against whom You assert such claim is referred to as
+“Participant”) alleging that the Participant Software (meaning the
+Contributor Version where the Participant is a Contributor or the Original
+Software where the Participant is the Initial Developer) directly or indirectly
+infringes any patent, then any and all rights granted directly or indirectly to
+You by such Participant, the Initial Developer (if the Initial Developer is not
+the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this
+License shall, upon 60 days notice from Participant terminate prospectively and
+automatically at the expiration of such 60 day notice period, unless if within
+such 60 day period You withdraw Your claim with respect to the Participant
+Software against such Participant either unilaterally or pursuant to a written
+agreement with Participant.
+6.3. If You assert a patent infringement claim
+against Participant alleging that the Participant Software directly or
+indirectly infringes any patent where such claim is resolved (such as by license
+or settlement) prior to the initiation of patent infringement litigation, then
+the reasonable value of the licenses granted by such Participant under Sections
+2.1 or 2.2 shall be taken into account in determining the amount or value of any
+payment or license.
+6.4. In the event of termination under Sections 6.1 or 6.2
+above, all end user licenses that have been validly granted by You or any
+distributor hereunder prior to termination (excluding licenses granted to You by
+any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY
+SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
+WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
+FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN
+IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS
+LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
+LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND
+LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+The Covered
+Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101
+(Oct. 1995), consisting of “commercial computer software” (as that term is
+defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software
+documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995).
+Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
+(June 1995), all U.S. Government End Users acquire Covered Software with only
+those rights set forth herein. This U.S. Government Rights clause is in lieu of,
+and supersedes, any other FAR, DFAR, or other clause or provision that addresses
+Government rights in computer software under this License.
+
+9. MISCELLANEOUS.
+
+This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable. This License shall be governed by the law of the
+jurisdiction specified in a notice contained within the Original Software
+(except to the extent applicable law, if any, provides otherwise), excluding
+such jurisdiction's conflict-of-law provisions. Any litigation relating to this
+License shall be subject to the jurisdiction of the courts located in the
+jurisdiction and venue specified in a notice contained within the Original
+Software, with the losing party responsible for costs, including, without
+limitation, court costs and reasonable attorneys' fees and expenses. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any law or regulation which provides that
+the language of a contract shall be construed against the drafter shall not
+apply to this License. You agree that You alone are responsible for compliance
+with the United States export administration regulations (and the export control
+laws and regulation of any other countries) when You use, distribute or
+otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer and the Contributors, each party is
+responsible for claims and damages arising, directly or indirectly, out of its
+utilization of rights under this License and You agree to work with Initial
+Developer and Contributors to distribute such responsibility on an equitable
+basis. Nothing herein is intended or shall be deemed to constitute any admission
+of liability.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+Protocol Buffer Java API 2.5.0
+--------------------------------------------------------------------------------
+This license applies to all parts of Protocol Buffers except the following:
+
+ - Atomicops support for generic gcc, located in
+ src/google/protobuf/stubs/atomicops_internals_generic_gcc.h.
+ This file is copyrighted by Red Hat Inc.
+
+ - Atomicops support for AIX/POWER, located in
+ src/google/protobuf/stubs/atomicops_internals_power.h.
+ This file is copyrighted by Bloomberg Finance LP.
+
+Copyright 2014, Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
+
+For:
+XML Commons External Components XML APIs 1.3.04
+--------------------------------------------------------------------------------
+By obtaining, using and/or copying this work, you (the licensee) agree that you
+have read, understood, and will comply with the following terms and conditions.
+
+Permission to copy, modify, and distribute this software and its documentation,
+with or without modification, for any purpose and without fee or royalty is
+hereby granted, provided that you include the following on ALL copies of the
+software and documentation or portions thereof, including modifications:
+- The full text of this NOTICE in a location viewable to users of the
+redistributed or derivative work.
+- Any pre-existing intellectual property disclaimers, notices, or terms and
+conditions. If none exist, the W3C Software Short Notice should be included
+(hypertext is preferred, text is permitted) within the body of any redistributed
+or derivative code.
+- Notice of any changes or modifications to the files, including the date changes
+were made. (We recommend you provide URIs to the location from which the code is
+derived.)
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+JUnit 4.11
+Eclipse JDT Core 3.1.1
+--------------------------------------------------------------------------------
+(EPL v1.0)
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are not
+derivative works of the Program.
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and such
+derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
+Patents to make, use, sell, offer to sell, import and otherwise transfer the
+Contribution of such Contributor, if any, in source code and object code form.
+This patent license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor, such
+addition of the Contribution causes such combination to be covered by the
+Licensed Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to
+its Contributions set forth herein, no assurances are provided by any
+Contributor that the Program does not infringe the patent or other intellectual
+property rights of any other entity. Each Contributor disclaims any liability to
+Recipient for claims brought by any other entity based on infringement of
+intellectual property rights or otherwise. As a condition to exercising the
+rights and licenses granted hereunder, each Recipient hereby assumes sole
+responsibility to secure any other intellectual property rights needed, if any.
+For example, if a third party patent license is required to allow Recipient to
+distribute the Program, it is Recipient's responsibility to acquire that license
+before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its
+own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title and
+non-infringement, and implied warranties or conditions of merchantability and
+fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by
+that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor,
+and informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor to
+control, and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may participate in
+any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its exercise of
+rights under this Agreement , including but not limited to the risks and costs
+of program errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Program itself
+(excluding combinations of the Program with other software or hardware)
+infringes such Recipient's patent(s), then such Recipient's rights granted under
+Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue and
+survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation
+may assign the responsibility to serve as the Agreement Steward to a suitable
+separate entity. Each new version of the Agreement will be given a
+distinguishing version number. The Program (including Contributions) may always
+be distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to distribute the Program (including its Contributions)
+under the new version. Except as expressly stated in Sections 2(a) and 2(b)
+above, Recipient receives no rights or licenses to the intellectual property of
+any Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted under
+this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial in
+any resulting litigation.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+JSch 0.1.54
+ParaNamer Core 2.3
+JLine 0.9.94
+leveldbjni-all 1.8
+Hamcrest Core 1.3
+ASM Core 5.0.4
+ASM Commons 5.0.2
+ASM Tree 5.0.2
+--------------------------------------------------------------------------------
+(3-clause BSD)
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+FindBugs-jsr305 3.0.0
+dnsjava 2.1.7, Copyright (c) 1998-2011, Brian Wellington. All rights reserved.
+--------------------------------------------------------------------------------
+(2-clause BSD)
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+"Java Concurrency in Practice" book annotations 1.0
+--------------------------------------------------------------------------------
+(CCAL v2.5)
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS
+PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR
+OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
+LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE
+BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
+HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
+
+1. Definitions
+
+"Collective Work" means a work, such as a periodical issue, anthology or
+encyclopedia, in which the Work in its entirety in unmodified form, along with a
+number of other contributions, constituting separate and independent works in
+themselves, are assembled into a collective whole. A work that constitutes a
+Collective Work will not be considered a Derivative Work (as defined below) for
+the purposes of this License.
+"Derivative Work" means a work based upon the Work or upon the Work and other
+pre-existing works, such as a translation, musical arrangement, dramatization,
+fictionalization, motion picture version, sound recording, art reproduction,
+abridgment, condensation, or any other form in which the Work may be recast,
+transformed, or adapted, except that a work that constitutes a Collective Work
+will not be considered a Derivative Work for the purpose of this License. For
+the avoidance of doubt, where the Work is a musical composition or sound
+recording, the synchronization of the Work in timed-relation with a moving image
+("synching") will be considered a Derivative Work for the purpose of this
+License.
+"Licensor" means the individual or entity that offers the Work under the terms
+of this License.
+"Original Author" means the individual or entity who created the Work.
+"Work" means the copyrightable work of authorship offered under the terms of
+this License.
+"You" means an individual or entity exercising rights under this License who has
+not previously violated the terms of this License with respect to the Work, or
+who has received express permission from the Licensor to exercise rights under
+this License despite a previous violation.
+2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or
+restrict any rights arising from fair use, first sale or other limitations on
+the exclusive rights of the copyright owner under copyright law or other
+applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License, Licensor
+hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
+duration of the applicable copyright) license to exercise the rights in the Work
+as stated below:
+
+to reproduce the Work, to incorporate the Work into one or more Collective
+Works, and to reproduce the Work as incorporated in the Collective Works;
+to create and reproduce Derivative Works;
+to distribute copies or phonorecords of, display publicly, perform publicly, and
+perform publicly by means of a digital audio transmission the Work including as
+incorporated in Collective Works;
+to distribute copies or phonorecords of, display publicly, perform publicly, and
+perform publicly by means of a digital audio transmission Derivative Works.
+For the avoidance of doubt, where the work is a musical composition:
+
+Performance Royalties Under Blanket Licenses. Licensor waives the exclusive
+right to collect, whether individually or via a performance rights society (e.g.
+ASCAP, BMI, SESAC), royalties for the public performance or public digital
+performance (e.g. webcast) of the Work.
+Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right
+to collect, whether individually or via a music rights agency or designated
+agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the
+Work ("cover version") and distribute, subject to the compulsory license created
+by 17 USC Section 115 of the US Copyright Act (or the equivalent in other
+jurisdictions).
+Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the
+Work is a sound recording, Licensor waives the exclusive right to collect,
+whether individually or via a performance-rights society (e.g. SoundExchange),
+royalties for the public digital performance (e.g. webcast) of the Work, subject
+to the compulsory license created by 17 USC Section 114 of the US Copyright Act
+(or the equivalent in other jurisdictions).
+The above rights may be exercised in all media and formats whether now known or
+hereafter devised. The above rights include the right to make such modifications
+as are technically necessary to exercise the rights in other media and formats.
+All rights not expressly granted by Licensor are hereby reserved.
+
+4. Restrictions.The license granted in Section 3 above is expressly made subject
+to and limited by the following restrictions:
+
+You may distribute, publicly display, publicly perform, or publicly digitally
+perform the Work only under the terms of this License, and You must include a
+copy of, or the Uniform Resource Identifier for, this License with every copy or
+phonorecord of the Work You distribute, publicly display, publicly perform, or
+publicly digitally perform. You may not offer or impose any terms on the Work
+that alter or restrict the terms of this License or the recipients' exercise of
+the rights granted hereunder. You may not sublicense the Work. You must keep
+intact all notices that refer to this License and to the disclaimer of
+warranties. You may not distribute, publicly display, publicly perform, or
+publicly digitally perform the Work with any technological measures that control
+access or use of the Work in a manner inconsistent with the terms of this
+License Agreement. The above applies to the Work as incorporated in a Collective
+Work, but this does not require the Collective Work apart from the Work itself
+to be made subject to the terms of this License. If You create a Collective
+Work, upon notice from any Licensor You must, to the extent practicable, remove
+from the Collective Work any credit as required by clause 4(b), as requested. If
+You create a Derivative Work, upon notice from any Licensor You must, to the
+extent practicable, remove from the Derivative Work any credit as required by
+clause 4(b), as requested.
+If you distribute, publicly display, publicly perform, or publicly digitally
+perform the Work or any Derivative Works or Collective Works, You must keep
+intact all copyright notices for the Work and provide, reasonable to the medium
+or means You are utilizing: (i) the name of the Original Author (or pseudonym,
+if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor
+designate another party or parties (e.g. a sponsor institute, publishing entity,
+journal) for attribution in Licensor's copyright notice, terms of service or by
+other reasonable means, the name of such party or parties; the title of the Work
+if supplied; to the extent reasonably practicable, the Uniform Resource
+Identifier, if any, that Licensor specifies to be associated with the Work,
+unless such URI does not refer to the copyright notice or licensing information
+for the Work; and in the case of a Derivative Work, a credit identifying the use
+of the Work in the Derivative Work (e.g., "French translation of the Work by
+Original Author," or "Screenplay based on original Work by Original Author").
+Such credit may be implemented in any reasonable manner; provided, however, that
+in the case of a Derivative Work or Collective Work, at a minimum such credit
+will appear where any other comparable authorship credit appears and in a manner
+at least as prominent as such other comparable authorship credit.
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS
+THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING
+THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,
+OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME
+JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH
+EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN
+NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
+INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS
+LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+This License and the rights granted hereunder will terminate automatically upon
+any breach by You of the terms of this License. Individuals or entities who have
+received Derivative Works or Collective Works from You under this License,
+however, will not have their licenses terminated provided such individuals or
+entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7,
+and 8 will survive any termination of this License.
+Subject to the above terms and conditions, the license granted here is perpetual
+(for the duration of the applicable copyright in the Work). Notwithstanding the
+above, Licensor reserves the right to release the Work under different license
+terms or to stop distributing the Work at any time; provided, however that any
+such election will not serve to withdraw this License (or any other license that
+has been, or is required to be, granted under the terms of this License), and
+this License will continue in full force and effect unless terminated as stated
+above.
+8. Miscellaneous
+
+Each time You distribute or publicly digitally perform the Work or a Collective
+Work, the Licensor offers to the recipient a license to the Work on the same
+terms and conditions as the license granted to You under this License.
+Each time You distribute or publicly digitally perform a Derivative Work,
+Licensor offers to the recipient a license to the original Work on the same
+terms and conditions as the license granted to You under this License.
+If any provision of this License is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this License, and without further action by the parties to this
+agreement, such provision shall be reformed to the minimum extent necessary to
+make such provision valid and enforceable.
+No term or provision of this License shall be deemed waived and no breach
+consented to unless such waiver or consent shall be in writing and signed by the
+party to be charged with such waiver or consent.
+This License constitutes the entire agreement between the parties with respect
+to the Work licensed here. There are no understandings, agreements or
+representations with respect to the Work not specified here. Licensor shall not
+be bound by any additional provisions that may appear in any communication from
+You. This License may not be modified without the mutual written agreement of
+the Licensor and You.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+jamon-runtime 2.4.1
+--------------------------------------------------------------------------------
+(MPL 2.0)
+ Mozilla Public License
+ Version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+means each individual or legal entity that creates, contributes to the creation
+of, or owns Covered Software.
+
+1.2. “Contributor Version”
+means the combination of the Contributions of others (if any) used by a
+Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+means Source Code Form to which the initial Contributor has attached the notice
+in Exhibit A, the Executable Form of such Source Code Form, and Modifications of
+such Source Code Form, in each case including portions thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+means
+
+that the initial Contributor has attached the notice described in Exhibit B to
+the Covered Software; or
+
+that the Covered Software was made available under the terms of version 1.1 or
+earlier of the License, but not also under the terms of a Secondary License.
+
+1.6. “Executable Form”
+means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+means a work that combines Covered Software with other material, in a separate
+file or files, that is not Covered Software.
+
+1.8. “License”
+means this document.
+
+1.9. “Licensable”
+means having the right to grant, to the maximum extent possible, whether at the
+time of the initial grant or subsequently, any and all of the rights conveyed by
+this License.
+
+1.10. “Modifications”
+means any of the following:
+
+any file in Source Code Form that results from an addition to, deletion from, or
+modification of the contents of Covered Software; or
+
+any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+means any patent claim(s), including without limitation, method, process, and
+apparatus claims, in any patent Licensable by such Contributor that would be
+infringed, but for the grant of the License, by the making, using, selling,
+offering for sale, having made, import, or transfer of either its Contributions
+or its Contributor Version.
+
+1.12. “Secondary License”
+means either the GNU General Public License, Version 2.0, the GNU Lesser General
+Public License, Version 2.1, the GNU Affero General Public License, Version 3.0,
+or any later versions of those licenses.
+
+1.13. “Source Code Form”
+means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+means an individual or a legal entity exercising rights under this License. For
+legal entities, “You” includes any entity that controls, is controlled by,
+or is under common control with You. For purposes of this definition,
+“control” means (a) the power, direct or indirect, to cause the direction or
+management of such entity, whether by contract or otherwise, or (b) ownership of
+more than fifty percent (50%) of the outstanding shares or beneficial ownership
+of such entity.
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive
+license:
+
+under intellectual property rights (other than patent or trademark) Licensable
+by such Contributor to use, reproduce, make available, modify, display, perform,
+distribute, and otherwise exploit its Contributions, either on an unmodified
+basis, with Modifications, or as part of a Larger Work; and
+
+under Patent Claims of such Contributor to make, use, sell, offer for sale, have
+made, import, and otherwise transfer either its Contributions or its Contributor
+Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution become
+effective for each Contribution on the date the Contributor first distributes
+such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under this
+License. No additional rights or licenses will be implied from the distribution
+or licensing of Covered Software under this License. Notwithstanding Section
+2.1(b) above, no patent license is granted by a Contributor:
+
+for any code that a Contributor has removed from Covered Software; or
+
+for infringements caused by: (i) Your and any other third party’s
+modifications of Covered Software, or (ii) the combination of its Contributions
+with other software (except as part of its Contributor Version); or
+
+under Patent Claims infringed by Covered Software in the absence of its
+Contributions.
+
+This License does not grant any rights in the trademarks, service marks, or
+logos of any Contributor (except as may be necessary to comply with the notice
+requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to distribute
+the Covered Software under a subsequent version of this License (see Section
+10.2) or under the terms of a Secondary License (if permitted under the terms of
+Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its Contributions are
+its original creation(s) or it has sufficient rights to grant the rights to its
+Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under applicable
+copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+Section 2.1.
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under the
+terms of this License. You must inform recipients that the Source Code Form of
+the Covered Software is governed by the terms of this License, and how they can
+obtain a copy of this License. You may not attempt to alter or restrict the
+recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+such Covered Software must also be made available in Source Code Form, as
+described in Section 3.1, and You must inform recipients of the Executable Form
+how they can obtain a copy of such Source Code Form by reasonable means in a
+timely manner, at a charge no more than the cost of distribution to the
+recipient; and
+
+You may distribute such Executable Form under the terms of this License, or
+sublicense it under different terms, provided that the license for the
+Executable Form does not attempt to limit or alter the recipients’ rights in
+the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice, provided
+that You also comply with the requirements of this License for the Covered
+Software. If the Larger Work is a combination of Covered Software with a work
+governed by one or more Secondary Licenses, and the Covered Software is not
+Incompatible With Secondary Licenses, this License permits You to additionally
+distribute such Covered Software under the terms of such Secondary License(s),
+so that the recipient of the Larger Work may, at their option, further
+distribute the Covered Software under the terms of either this License or such
+Secondary License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices (including
+copyright notices, patent notices, disclaimers of warranty, or limitations of
+liability) contained within the Source Code Form of the Covered Software, except
+that You may alter any license notices to the extent required to remedy known
+factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support, indemnity
+or liability obligations to one or more recipients of Covered Software. However,
+You may do so only on Your own behalf, and not on behalf of any Contributor. You
+must make it absolutely clear that any such warranty, support, indemnity, or
+liability obligation is offered by You alone, and You hereby agree to indemnify
+every Contributor for any liability incurred by such Contributor as a result of
+warranty, support, indemnity or liability terms You offer. You may include
+additional disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+If it is impossible for You to comply with any of the terms of this License with
+respect to some or all of the Covered Software due to statute, judicial order,
+or regulation then You must: (a) comply with the terms of this License to the
+maximum extent possible; and (b) describe the limitations and the code they
+affect. Such description must be placed in a text file included with all
+distributions of the Covered Software under this License. Except to the extent
+prohibited by statute or regulation, such description must be sufficiently
+detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+fail to comply with any of its terms. However, if You become compliant, then the
+rights granted under this License from a particular Contributor are reinstated
+(a) provisionally, unless and until such Contributor explicitly and finally
+terminates Your grants, and (b) on an ongoing basis, if such Contributor fails
+to notify You of the non-compliance by some reasonable means prior to 60 days
+after You have come back into compliance. Moreover, Your grants from a
+particular Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the first
+time You have received notice of non-compliance with this License from such
+Contributor, and You become compliant prior to 30 days after Your receipt of the
+notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions, counter-claims, and
+cross-claims) alleging that a Contributor Version directly or indirectly
+infringes any patent, then the rights granted to You by any and all Contributors
+for the Covered Software under Section 2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+license agreements (excluding distributors and resellers) which have been
+validly granted by You or Your distributors under this License prior to
+termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+Covered Software is provided under this License on an “as is” basis, without
+warranty of any kind, either expressed, implied, or statutory, including,
+without limitation, warranties that the Covered Software is free of defects,
+merchantable, fit for a particular purpose or non-infringing. The entire risk as
+to the quality and performance of the Covered Software is with You. Should any
+Covered Software prove defective in any respect, You (not any Contributor)
+assume the cost of any necessary servicing, repair, or correction. This
+disclaimer of warranty constitutes an essential part of this License. No use of
+any Covered Software is authorized under this License except under this
+disclaimer.
+
+7. Limitation of Liability
+
+Under no circumstances and under no legal theory, whether tort (including
+negligence), contract, or otherwise, shall any Contributor, or anyone who
+distributes Covered Software as permitted above, be liable to You for any
+direct, indirect, special, incidental, or consequential damages of any character
+including, without limitation, damages for lost profits, loss of goodwill, work
+stoppage, computer failure or malfunction, or any and all other commercial
+damages or losses, even if such party shall have been informed of the
+possibility of such damages. This limitation of liability shall not apply to
+liability for death or personal injury resulting from such party’s negligence
+to the extent applicable law prohibits such limitation. Some jurisdictions do
+not allow the exclusion or limitation of incidental or consequential damages, so
+this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+Any litigation relating to this License may be brought only in the courts of a
+jurisdiction where the defendant maintains its principal place of business and
+such litigation shall be governed by laws of that jurisdiction, without
+reference to its conflict-of-law provisions. Nothing in this Section shall
+prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+This License represents the complete agreement concerning the subject matter
+hereof. If any provision of this License is held to be unenforceable, such
+provision shall be reformed only to the extent necessary to make it enforceable.
+Any law or regulation which provides that the language of a contract shall be
+construed against the drafter shall not be used to construe this License against
+a Contributor.
+
+10. Versions of the License
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section 10.3,
+no one other than the license steward has the right to modify or publish new
+versions of this License. Each version will be given a distinguishing version
+number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version of the
+License under which You originally received the Covered Software, or under the
+terms of any subsequent version published by the license steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to create a
+new license for such software, you may create and use a modified version of this
+License if you rename the license and remove any references to the name of the
+license steward (except to note that such modified license differs from this
+License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With Secondary
+Licenses under the terms of this version of the License, the notice described in
+Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+This Source Code Form is subject to the terms of the Mozilla Public License, v.
+2.0. If a copy of the MPL was not distributed with this file, You can obtain one
+at https://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+This Source Code Form is “Incompatible With Secondary Licenses”, as defined
+by the Mozilla Public License, v. 2.0.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+JDOM 1.1
+--------------------------------------------------------------------------------
+/*--
+
+ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact .
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management .
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter and
+ Brett McLaughlin . For more information
+ on the JDOM Project, please see .
+
+ */
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+Hbase Server 1.2.4
+--------------------------------------------------------------------------------
+This project bundles a derivative image for our Orca Logo. This image is
+available under the Creative Commons By Attribution 3.0 License.
+
+ Creative Commons Legal Code
+
+ Attribution 3.0 Unported
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
+ DAMAGES RESULTING FROM ITS USE.
+
+ License
+
+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+ COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+ COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+ AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+ TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
+ BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
+ CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
+ CONDITIONS.
+
+ 1. Definitions
+
+ a. "Adaptation" means a work based upon the Work, or upon the Work and
+ other pre-existing works, such as a translation, adaptation,
+ derivative work, arrangement of music or other alterations of a
+ literary or artistic work, or phonogram or performance and includes
+ cinematographic adaptations or any other form in which the Work may be
+ recast, transformed, or adapted including in any form recognizably
+ derived from the original, except that a work that constitutes a
+ Collection will not be considered an Adaptation for the purpose of
+ this License. For the avoidance of doubt, where the Work is a musical
+ work, performance or phonogram, the synchronization of the Work in
+ timed-relation with a moving image ("synching") will be considered an
+ Adaptation for the purpose of this License.
+ b. "Collection" means a collection of literary or artistic works, such as
+ encyclopedias and anthologies, or performances, phonograms or
+ broadcasts, or other works or subject matter other than works listed
+ in Section 1(f) below, which, by reason of the selection and
+ arrangement of their contents, constitute intellectual creations, in
+ which the Work is included in its entirety in unmodified form along
+ with one or more other contributions, each constituting separate and
+ independent works in themselves, which together are assembled into a
+ collective whole. A work that constitutes a Collection will not be
+ considered an Adaptation (as defined above) for the purposes of this
+ License.
+ c. "Distribute" means to make available to the public the original and
+ copies of the Work or Adaptation, as appropriate, through sale or
+ other transfer of ownership.
+ d. "Licensor" means the individual, individuals, entity or entities that
+ offer(s) the Work under the terms of this License.
+ e. "Original Author" means, in the case of a literary or artistic work,
+ the individual, individuals, entity or entities who created the Work
+ or if no individual or entity can be identified, the publisher; and in
+ addition (i) in the case of a performance the actors, singers,
+ musicians, dancers, and other persons who act, sing, deliver, declaim,
+ play in, interpret or otherwise perform literary or artistic works or
+ expressions of folklore; (ii) in the case of a phonogram the producer
+ being the person or legal entity who first fixes the sounds of a
+ performance or other sounds; and, (iii) in the case of broadcasts, the
+ organization that transmits the broadcast.
+ f. "Work" means the literary and/or artistic work offered under the terms
+ of this License including without limitation any production in the
+ literary, scientific and artistic domain, whatever may be the mode or
+ form of its expression including digital form, such as a book,
+ pamphlet and other writing; a lecture, address, sermon or other work
+ of the same nature; a dramatic or dramatico-musical work; a
+ choreographic work or entertainment in dumb show; a musical
+ composition with or without words; a cinematographic work to which are
+ assimilated works expressed by a process analogous to cinematography;
+ a work of drawing, painting, architecture, sculpture, engraving or
+ lithography; a photographic work to which are assimilated works
+ expressed by a process analogous to photography; a work of applied
+ art; an illustration, map, plan, sketch or three-dimensional work
+ relative to geography, topography, architecture or science; a
+ performance; a broadcast; a phonogram; a compilation of data to the
+ extent it is protected as a copyrightable work; or a work performed by
+ a variety or circus performer to the extent it is not otherwise
+ considered a literary or artistic work.
+ g. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License with
+ respect to the Work, or who has received express permission from the
+ Licensor to exercise rights under this License despite a previous
+ violation.
+ h. "Publicly Perform" means to perform public recitations of the Work and
+ to communicate to the public those public recitations, by any means or
+ process, including by wire or wireless means or public digital
+ performances; to make available to the public Works in such a way that
+ members of the public may access these Works from a place and at a
+ place individually chosen by them; to perform the Work to the public
+ by any means or process and the communication to the public of the
+ performances of the Work, including by public digital performance; to
+ broadcast and rebroadcast the Work by any means including signs,
+ sounds or images.
+ i. "Reproduce" means to make copies of the Work by any means including
+ without limitation by sound or visual recordings and the right of
+ fixation and reproducing fixations of the Work, including storage of a
+ protected performance or phonogram in digital form or other electronic
+ medium.
+
+ 2. Fair Dealing Rights. Nothing in this License is intended to reduce,
+ limit, or restrict any uses free from copyright or rights arising from
+ limitations or exceptions that are provided for in connection with the
+ copyright protection under copyright law or other applicable laws.
+
+ 3. License Grant. Subject to the terms and conditions of this License,
+ Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+ perpetual (for the duration of the applicable copyright) license to
+ exercise the rights in the Work as stated below:
+
+ a. to Reproduce the Work, to incorporate the Work into one or more
+ Collections, and to Reproduce the Work as incorporated in the
+ Collections;
+ b. to create and Reproduce Adaptations provided that any such Adaptation,
+ including any translation in any medium, takes reasonable steps to
+ clearly label, demarcate or otherwise identify that changes were made
+ to the original Work. For example, a translation could be marked "The
+ original work was translated from English to Spanish," or a
+ modification could indicate "The original work has been modified.";
+ c. to Distribute and Publicly Perform the Work including as incorporated
+ in Collections; and,
+ d. to Distribute and Publicly Perform Adaptations.
+ e. For the avoidance of doubt:
+
+ i. Non-waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or
+ compulsory licensing scheme cannot be waived, the Licensor
+ reserves the exclusive right to collect such royalties for any
+ exercise by You of the rights granted under this License;
+ ii. Waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or
+ compulsory licensing scheme can be waived, the Licensor waives the
+ exclusive right to collect such royalties for any exercise by You
+ of the rights granted under this License; and,
+ iii. Voluntary License Schemes. The Licensor waives the right to
+ collect royalties, whether individually or, in the event that the
+ Licensor is a member of a collecting society that administers
+ voluntary licensing schemes, via that society, from any exercise
+ by You of the rights granted under this License.
+
+ The above rights may be exercised in all media and formats whether now
+ known or hereafter devised. The above rights include the right to make
+ such modifications as are technically necessary to exercise the rights in
+ other media and formats. Subject to Section 8(f), all rights not expressly
+ granted by Licensor are hereby reserved.
+
+ 4. Restrictions. The license granted in Section 3 above is expressly made
+ subject to and limited by the following restrictions:
+
+ a. You may Distribute or Publicly Perform the Work only under the terms
+ of this License. You must include a copy of, or the Uniform Resource
+ Identifier (URI) for, this License with every copy of the Work You
+ Distribute or Publicly Perform. You may not offer or impose any terms
+ on the Work that restrict the terms of this License or the ability of
+ the recipient of the Work to exercise the rights granted to that
+ recipient under the terms of the License. You may not sublicense the
+ Work. You must keep intact all notices that refer to this License and
+ to the disclaimer of warranties with every copy of the Work You
+ Distribute or Publicly Perform. When You Distribute or Publicly
+ Perform the Work, You may not impose any effective technological
+ measures on the Work that restrict the ability of a recipient of the
+ Work from You to exercise the rights granted to that recipient under
+ the terms of the License. This Section 4(a) applies to the Work as
+ incorporated in a Collection, but this does not require the Collection
+ apart from the Work itself to be made subject to the terms of this
+ License. If You create a Collection, upon notice from any Licensor You
+ must, to the extent practicable, remove from the Collection any credit
+ as required by Section 4(b), as requested. If You create an
+ Adaptation, upon notice from any Licensor You must, to the extent
+ practicable, remove from the Adaptation any credit as required by
+ Section 4(b), as requested.
+ b. If You Distribute, or Publicly Perform the Work or any Adaptations or
+ Collections, You must, unless a request has been made pursuant to
+ Section 4(a), keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i) the
+ name of the Original Author (or pseudonym, if applicable) if supplied,
+ and/or if the Original Author and/or Licensor designate another party
+ or parties (e.g., a sponsor institute, publishing entity, journal) for
+ attribution ("Attribution Parties") in Licensor's copyright notice,
+ terms of service or by other reasonable means, the name of such party
+ or parties; (ii) the title of the Work if supplied; (iii) to the
+ extent reasonably practicable, the URI, if any, that Licensor
+ specifies to be associated with the Work, unless such URI does not
+ refer to the copyright notice or licensing information for the Work;
+ and (iv) , consistent with Section 3(b), in the case of an Adaptation,
+ a credit identifying the use of the Work in the Adaptation (e.g.,
+ "French translation of the Work by Original Author," or "Screenplay
+ based on original Work by Original Author"). The credit required by
+ this Section 4 (b) may be implemented in any reasonable manner;
+ provided, however, that in the case of a Adaptation or Collection, at
+ a minimum such credit will appear, if a credit for all contributing
+ authors of the Adaptation or Collection appears, then as part of these
+ credits and in a manner at least as prominent as the credits for the
+ other contributing authors. For the avoidance of doubt, You may only
+ use the credit required by this Section for the purpose of attribution
+ in the manner set out above and, by exercising Your rights under this
+ License, You may not implicitly or explicitly assert or imply any
+ connection with, sponsorship or endorsement by the Original Author,
+ Licensor and/or Attribution Parties, as appropriate, of You or Your
+ use of the Work, without the separate, express prior written
+ permission of the Original Author, Licensor and/or Attribution
+ Parties.
+ c. Except as otherwise agreed in writing by the Licensor or as may be
+ otherwise permitted by applicable law, if You Reproduce, Distribute or
+ Publicly Perform the Work either by itself or as part of any
+ Adaptations or Collections, You must not distort, mutilate, modify or
+ take other derogatory action in relation to the Work which would be
+ prejudicial to the Original Author's honor or reputation. Licensor
+ agrees that in those jurisdictions (e.g. Japan), in which any exercise
+ of the right granted in Section 3(b) of this License (the right to
+ make Adaptations) would be deemed to be a distortion, mutilation,
+ modification or other derogatory action prejudicial to the Original
+ Author's honor and reputation, the Licensor will waive or not assert,
+ as appropriate, this Section, to the fullest extent permitted by the
+ applicable national law, to enable You to reasonably exercise Your
+ right under Section 3(b) of this License (right to make Adaptations)
+ but not otherwise.
+
+ 5. Representations, Warranties and Disclaimer
+
+ UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+ OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+ KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+ LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+ WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
+ OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+ 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+ LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 7. Termination
+
+ a. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Adaptations or Collections
+ from You under this License, however, will not have their licenses
+ terminated provided such individuals or entities remain in full
+ compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
+ survive any termination of this License.
+ b. Subject to the above terms and conditions, the license granted here is
+ perpetual (for the duration of the applicable copyright in the Work).
+ Notwithstanding the above, Licensor reserves the right to release the
+ Work under different license terms or to stop distributing the Work at
+ any time; provided, however that any such election will not serve to
+ withdraw this License (or any other license that has been, or is
+ required to be, granted under the terms of this License), and this
+ License will continue in full force and effect unless terminated as
+ stated above.
+
+ 8. Miscellaneous
+
+ a. Each time You Distribute or Publicly Perform the Work or a Collection,
+ the Licensor offers to the recipient a license to the Work on the same
+ terms and conditions as the license granted to You under this License.
+ b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
+ offers to the recipient a license to the original Work on the same
+ terms and conditions as the license granted to You under this License.
+ c. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this License, and without further action
+ by the parties to this agreement, such provision shall be reformed to
+ the minimum extent necessary to make such provision valid and
+ enforceable.
+ d. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in writing
+ and signed by the party to be charged with such waiver or consent.
+ e. This License constitutes the entire agreement between the parties with
+ respect to the Work licensed here. There are no understandings,
+ agreements or representations with respect to the Work not specified
+ here. Licensor shall not be bound by any additional provisions that
+ may appear in any communication from You. This License may not be
+ modified without the mutual written agreement of the Licensor and You.
+ f. The rights granted under, and the subject matter referenced, in this
+ License were drafted utilizing the terminology of the Berne Convention
+ for the Protection of Literary and Artistic Works (as amended on
+ September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
+ Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
+ and the Universal Copyright Convention (as revised on July 24, 1971).
+ These rights and subject matter take effect in the relevant
+ jurisdiction in which the License terms are sought to be enforced
+ according to the corresponding provisions of the implementation of
+ those treaty provisions in the applicable national law. If the
+ standard suite of rights granted under applicable copyright law
+ includes additional rights not granted under this License, such
+ additional rights are deemed to be included in the License; this
+ License is not intended to restrict the license of any rights under
+ applicable law.
+
+
+ Creative Commons Notice
+
+ Creative Commons is not a party to this License, and makes no warranty
+ whatsoever in connection with the Work. Creative Commons will not be
+ liable to You or any party on any legal theory for any damages
+ whatsoever, including without limitation any general, special,
+ incidental or consequential damages arising in connection to this
+ license. Notwithstanding the foregoing two (2) sentences, if Creative
+ Commons has expressly identified itself as the Licensor hereunder, it
+ shall have all rights and obligations of Licensor.
+
+ Except for the limited purpose of indicating to the public that the
+ Work is licensed under the CCPL, Creative Commons does not authorize
+ the use by either party of the trademark "Creative Commons" or any
+ related trademark or logo of Creative Commons without the prior
+ written consent of Creative Commons. Any permitted use will be in
+ compliance with Creative Commons' then-current trademark usage
+ guidelines, as may be published on its website or otherwise made
+ available upon request from time to time. For the avoidance of doubt,
+ this trademark restriction does not form part of this License.
+
+ Creative Commons may be contacted at https://creativecommons.org/.
+
+--------------------------------------------------------------------------------
+
+For: /hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server
+/hadoop-yarn-server-nodemanager/src/main/resources/TERMINAL
+
+xterm.js 3.8.0
+The source and binary distribution of this product bundles these dependencies
+under the following license:
+
+Copyright (c) 2017-2018, The xterm.js authors (https://github.com/xtermjs/xterm.js)
+Copyright (c) 2014-2016, SourceLair Private Company (https://www.sourcelair.com)
+Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+--------------------------------------------------------------------------------
+
+For: hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs
+/server/datanode/checker/AbstractFuture.java and
+hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs
+/server/datanode/checker/TimeoutFuture.java
+
+Copyright (C) 2007 The Guava Authors
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+
+--------------------------------------------------------------------------------
+
+Jline 3.9.0
+The binary distribution of this product bundles these dependencies under the
+following license:
+
+Copyright (c) 2002-2018, the original author or authors.
+All rights reserved.
+
+http://www.opensource.org/licenses/bsd-license.php
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with
+the distribution.
+
+Neither the name of JLine nor the names of its contributors
+may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/dev-support/submarine-installer/README-CN.md b/dev-support/submarine-installer/README-CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..82a3baf4862d4c27c82e49b2c71e92d08f1b0e82
--- /dev/null
+++ b/dev-support/submarine-installer/README-CN.md
@@ -0,0 +1,228 @@
+# submarine installer
+
+## 项目介绍
+
+介绍 **submarine-installer** 项目之前,首先要说明一下 **Submarine** 这个项目,**Submarine** 是 apache 顶级的机器学习平台项目。他将致力于支持 `Tensorflow`、`MXNet`、`Caffe`、`Spark` 等多种深度学习框架,提供了机器学习算法开发、分布式模型训练、模型管理和模型发布等全功能的系统框架,结合 hadoop 与身俱来的数据存储和数据处理能力,让数据科学家们能够更好的挖掘和发挥出数据的价值。
+
+hadoop 在 2.9 版本中就已经让 YARN 支持了 Docker 容器的资源调度模式,**Submarine** 在此基础之上通过 YARN 把分布式深度学习框架以 Docker 容器的方式进行调度和运行起来。
+
+由于分布式深度学习框架需要运行在多个 Docker 的容器之中,并且需要能够让运行在容器之中的各个服务相互协调,完成分布式机器学习的模型训练和模型发布等服务,这其中就会牵涉到 `DNS`、`Docker` 、 `GPU`、`Network`、`显卡`、`操作系统内核` 修改等多个系统工程问题,正确的部署好 **Hadoop {Submarine}** 的运行环境是一件很困难和耗时的事情。
+
+为了降低 hadoop 2.9 以上版本的 docker 等组件的部署难度,所以我们专门开发了这个用来部署 `Submarine` 运行时环境的 `submarine-installer` 项目,提供一键安装脚本,也可以分步执行安装、卸载、启动和停止各个组件,同时讲解每一步主要参数配置和注意事项。我们同时提供了 [中文手册](project/github/submarine/docs/userdocs/yarn/InstallationGuideChineseVersion.md) 和 [英文手册](project/github/submarine/docs/userdocs/yarn/InstallationGuide.md) ,帮助用户更容易的部署,发现问题也可以及时解决。
+
+## 先决条件
+
+**submarine-installer** 目前只支持 `centos-release-7-3.1611.el7.centos.x86_64` 以上版本的操作系统中进行使用。
+
+## 配置说明
+
+使用 **submarine-installer** 进行部署之前,你可以参考 [install.conf](install.conf) 文件中已有的配置参数和格式,根据你的使用情况进行如下的参数配置:
+
++ **DNS 配置项**
+
+ LOCAL_DNS_HOST:服务器端本地 DNS IP 地址配置,可以从 `/etc/resolv.conf` 中查看
+
+ YARN_REGISTRY_DNS_HOST:yarn dns server 启动的 IP 地址
+
++ **ETCD 配置项**
+
+ 机器学习是一个计算密度型系统,对数据传输性能要求非常高,所以我们使用了网络效率损耗最小的 ETCD 网络组件,它可以通过 BGP 路由方式支持 overlay 网络,同时在跨机房部署时支持隧道模式。
+
+ 你需要选择至少三台以上的服务器作为 ETCD 的运行服务器,这样可以让 `Submarine` 有较好的容错性和稳定性。
+
+ 在 **ETCD_HOSTS** 配置项中输入作为 ETCD 服务器的IP数组,参数配置一般是这样:
+
+ ETCD_HOSTS=(hostIP1 hostIP2 hostIP3),注意多个 hostIP 之间请使用空格进行隔开。
+
++ **DOCKER_REGISTRY 配置项**
+
+ 你首先需要安装好一个可用的 docker 的镜像管理仓库,这个镜像仓库用来存放你所需要的各种深度学习框架的镜像文件,然后将镜像仓库的 IP 地址和端口配置进来,参数配置一般是这样:DOCKER_REGISTRY="10.120.196.232:5000"
+
++ **DOWNLOAD_SERVER 配置项**
+
+ `submarine-installer` 默认都是从网络上直接下载所有的依赖包(例如:GCC、Docker、Nvidia 驱动等等),这往往需要消耗大量的时间,并且在有些服务器不能连接互联网的环境中将无法部署,所以我们在 `submarine-installer` 中内置了 HTTP 下载服务,只需要在一台能够连接互联网的服务器中运行 `submarine-installer` ,就可以为所有其他服务器提供依赖包的下载,只需要你按照以下配置进行操作:
+
+ 1. 首先,你需要将 `DOWNLOAD_SERVER_IP` 配置为一台能够连接互联网的服务器IP地址,将 `DOWNLOAD_SERVER_PORT` 配置为一个不会不太常用的端口。
+ 2. 在 `DOWNLOAD_SERVER_IP` 所在的那台服务器中运行 `submarine-installer/install.sh` 命令后,在安装界面中选择 `[start download server]` 菜单项,`submarine-installer` 将会把部署所有的依赖包全部下载到 `submarine-installer/downloads` 目录中,然后通过 `python -m SimpleHTTPServer ${DOWNLOAD_SERVER_PORT}` 命令启动一个 HTTP 下载服务,不要关闭这台服务器中运行着的 `submarine-installer` 。
+ 3. 在其他服务器中同样运行 `submarine-installer/install.sh` 命令 ,按照安装界面中的 `[install component]` 菜单依次进行各个组件的安装时,会自动从 `DOWNLOAD_SERVER_IP` 所在的那台服务器下载依赖包进行安装部署。
+ 4. **DOWNLOAD_SERVER** 另外还有一个用处是,你可以自行把各个依赖包手工下载下来,然后放到其中一台服务器的 `submarine-installer/downloads` 目录中,然后开启 `[start download server]` ,这样就可以为整个集群提供离线安装部署的能力。
+
++ **YARN_CONTAINER_EXECUTOR_PATH 配置项**
+
+ 如何编译 YARN 的 container-executor:你进入到 `hadoop/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager` 目录中执行 `mvn package -Pnative -DskipTests` 命令,将会编译出 `./target/native/target/usr/local/bin/container-executor` 文件。
+
+ 你需要将 `container-executor` 文件的完整路径填写在 YARN_CONTAINER_EXECUTOR_PATH 配置项中。
+
++ **YARN_HIERARCHY 配置项**
+
+ 请保持和你所使用的 YARN 集群的 `yarn-site.xml` 配置文件中的 `yarn.nodemanager.linux-container-executor.cgroups.hierarchy` 相同的配置,`yarn-site.xml` 中如果未配置该项,那么默认为 `/hadoop-yarn`。
+
++ **YARN_NODEMANAGER_LOCAL_DIRS 配置项**
+
+ 请保持和你所使用的 YARN 集群的 `yarn-site.xml` 配置文件中的 `yarn.nodemanager.local-dirs` 相同的配置。
+
++ **YARN_NODEMANAGER_LOG_DIRS 配置项**
+
+ 请保持和你所使用的 YARN 集群的 `yarn-site.xml` 配置文件中的 `yarn.nodemanager.log-dirs` 相同的配置。
+
+## 使用说明
+
+**submarine-installer** 完全使用 Shell 脚本编写,不需要安装 ansible 等任何部署工具,避免了不同公司用户的服务器管理规范不同而导致程序不通用,例如:有些机房是不容许 ROOT 用户通过 SHELL 直接进行远程服务器操作等。
+
+**submarine-installer** 的部署过程,完全是通过在菜单中进行选择的操作方式进行的,避免了误操作的同时,你还可以通过各个菜单项目对任意一个组件进行分步执行安装、卸载、启动和停止各个组件,具有很好的灵活性,在部分组件出现问题后,也可以通过 **submarine-installer** 对系统进行诊断和修复。
+
+**submarine-installer** 部署过程中屏幕中会显示日志信息,日志信息一共有三种字体颜色:
+
++ 红色字体颜色:说明组件安装出现了错误,部署已经终止。
+
++ 绿色文字颜色:说明组件安装正常,部署正常运行。
+
++ 蓝色文字颜色:需要你按照提示信息在另外一个 SHELL 终端中进行手工输入命令,一般是修改操作系统内核配置操作,按照提示信息依次操作就可以了。
+
+**启动 submarine-installer**
+
+运行 `submarine-installer/install.sh` 命令启动,部署程序首先会检测服务器中的网卡 IP 地址,如果服务器有多个网卡或配置了多个 IP ,会以列表的形式显示,选择你实际使用的 IP 地址。
+
+**submarine-installer** 菜单说明:
+
+
+
+## 部署说明
+
+部署流程如下所示:
+
+1. 参照配置说明,根据你的服务器使用情况配置好 install.conf 文件
+
+2. 将整个 `submarine-installer` 文件夹打包复制到所有的服务器节点中
+
+3. 首先在配置为 **DOWNLOAD_SERVER** 的服务器中
+
+ + 运行 `submarine-installer/install.sh` 命令
+
+ + 在安装界面中选择 `[start download server]` 菜单项,等待下载完各个依赖包后,启动 HTTP 服务
+
+4. 在其他需要进行部署的服务器中
+
+ 运行 `submarine-installer/install.sh` 命令,显示的主菜单 **[Main menu]** 中有以下菜单:
+
+ + prepare system environment
+ + install component
+ + uninstall component
+ + start component
+ + stop component
+ + start download server
+
+5. **prepare system environment**
+
+ + **prepare operation system**
+
+ 检查部署服务器的操作系统和版本;
+
+ + **prepare operation system kernel**
+
+ 显示操作系统内核更新的操作命令的提示信息,根据你的选择是否自动更新内核版本;
+
+ + **prepare GCC version**
+
+ 显示操作系统中现在的 GCC 版本内核更新的操作命令的提示信息和根据你的选择是否自动更新 GCC 版本;
+
+ + **check GPU**
+
+ 检查服务器是否能够检测到 GPU 显卡;
+
+ + **prepare user&group**
+
+ 显示添加 hadoop 和 docker 的用户和用户组操作命令的提示信息,需要你自己根据提示信息检查服务器中是否存在所需要的用户和用户组;
+
+ + **prepare nvidia environment**
+
+ 自动进行操作系统内核和头文件的更新,自动安装 `epel-release` 和 `dkms` ;
+
+ 显示修改系统内核参数配置的操作命令的提示信息,需要你另外打开一个终端根据命令顺序执行;
+
+6. install component
+
+ + **install etcd**
+
+ 下载 etcd 的 bin 文件,并安装到 `/usr/bin` 目录中;
+
+ 根据 **ETCD_HOSTS** 配置项生成 `etcd.service` 文件, 安装到 `/etc/systemd/system/` 目录中;
+
+ + **install docker**
+
+ 下载 docker 的 RPM 包进行本地安装;
+
+ 生成 `daemon.json` 配置文件,安装到 `/etc/docker/` 目录中;
+
+ 生成 `docker.service` 配置文件,安装到 `/etc/systemd/system/` 目录中;
+
+ + **install calico network**
+
+ 下载 `calico` 、`calicoctl` 和 `calico-ipam` 文件,安装到 `/usr/bin` 目录中;
+
+ 生成 `calicoctl.cfg` 配置文件,安装到 `/etc/calico/` 目录中;
+
+ 生成 `calico-node.service` 配置文件,安装到 `/etc/systemd/system/` 目录中;
+
+ 安装完毕后,会在容器中会根据 **CALICO_NETWORK_NAME** 配置项自动创建 calico network,并自动创建 2 个 Docker 容器,检查 2 个容器是否能偶互相 PING 通;
+
+ + **install nvidia driver**
+
+ 下载 `nvidia-detect` 文件,在服务器中检测显卡版本;
+
+ 根据显卡版本号下载 Nvidia 显卡驱动安装包;
+
+ 检测本服务器中是否 `disabled Nouveau` ,如果没有停止安装,那么你需要执行 **[prepare system environment]** 菜单中的 **[prepare nvidia environment]** 子菜单项,按照提示进行操作;
+
+ 如果本服务器中已经 `disabled Nouveau` ,那么就会进行本地安装;
+
+ + **install nvidia docker**
+
+ 下载 `nvidia-docker` 的 RPM 安装包并进行安装;
+
+ 显示检测 `nvidia-docker` 是否可用的命令提示信息,需要你另外打开一个终端根据命令顺序执行;
+
+ + **install yarn container-executor**
+
+ 根据 **YARN_CONTAINER_EXECUTOR_PATH 配置项**,将 `container-executor` 文件复制到 `/etc/yarn/sbin/Linux-amd64-64/` 目录中;
+
+ 根据配置生成 `container-executor.cfg` 文件,复制到 `/etc/yarn/sbin/etc/hadoop/` 目录中;
+
+ + **install submarine autorun script**
+
+ 复制 `submarine.sh` 文件到 `/etc/rc.d/init.d/` 目录中;
+
+ 将 `/etc/rc.d/init.d/submarine.sh` 添加到 `/etc/rc.d/rc.local` 系统自启动文件中;
+
+7. uninstall component
+
+ 删除指定组件的 BIN 文件和配置文件,不在复述
+
+ - uninstall etcd
+ - uninstall docker
+ - uninstall calico network
+ - uninstall nvidia driver
+ - uninstall nvidia docker
+ - uninstall yarn container-executor
+ - uninstall submarine autorun script
+
+8. start component
+
+ 重启指定组件,不在复述
+
+ - start etcd
+ - start docker
+ - start calico network
+
+9. stop component
+
+ 停止指定组件,不在复述
+
+ - stop etcd
+ - stop docker
+ - stop calico network
+
+10. start download server
+
+ 只能在 **DOWNLOAD_SERVER_IP 配置项** 所在的服务器中才能执行本操作;
+
diff --git a/dev-support/submarine-installer/README.md b/dev-support/submarine-installer/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9acd420f69bbd70c8a68cc9d4ff0053af6328e36
--- /dev/null
+++ b/dev-support/submarine-installer/README.md
@@ -0,0 +1,236 @@
+
+# submarine installer
+
+## Introduction
+
+Submarine is the latest machine learning framework. It aims to support `Tensorflow`, `MXNet`,` Caffe`, `Spark`, etc. A variety of deep learning frameworks provide a full-featured system framework for machine learning algorithm development, distributed model training, model management, and model publishing, combined with hadoop's intrinsic data storage and data processing capabilities to enable data scientists to Good mining and the value of the data.
+
+Hadoop has enabled YARN to support Docker container since 2.x. **Submarine** then uses YARN to schedule and run the distributed deep learning framework in the form of a Docker container.
+
+Since the distributed deep learning framework needs to run in multiple Docker containers and needs to be able to coordinate the various services running in the container, complete the services of model training and model publishing for distributed machine learning. Involving multiple system engineering problems such as `DNS`, `Docker`, `GPU`, `Network`, `graphics card`, `operating system kernel` modification, etc. It is very difficult and time-consuming to properly deploy the **Submarine** runtime environment.
+
+In order to reduce the difficulty of deploying components, we have developed this **submarine-installer** project to deploy the **Submarine** runtime environment, providing a one-click installation script or step-by-step installation. Unload, start, and stop individual components, and explain the main parameter configuration and considerations for each step. We also provides a [Chinese manual](project/github/submarine/docs/userdocs/yarn/InstallationGuideChineseVersion.md) and an [English manual](project/github/submarine/docs/userdocs/yarn/InstallationGuide.md) for the **Submarine** runtime environment to help users deploy more easily and find problems in a timely manner.
+
+This installer is just created for your convenience and for test purpose only. You can choose to install required libraries by yourself, please don't run this script in your production environment before fully validate it in a sandbox environment.
+
+## prerequisites
+
+**submarine-installer** currently only supports operating systems based on `centos-release-7-3.1611.el7.centos.x86_64` and above.
+
+## Configuration instructions
+
+Before deploying with submarine-installer, you can refer to the existing configuration parameters and format in the `install.conf` file, and configure the following parameters according to your usage:
+
++ **DNS Configuration**
+
+ LOCAL_DNS_HOST: server-side local DNS IP address configuration, which can be viewed from `/etc/resolv.conf`
+
+ YARN_REGISTRY_DNS_HOST: yarn dns server started IP address
+
++ **ETCD Configuration**
+
+ Machine learning is a computationally-density system that requires very high data transmission performance. Therefore, we use the ETCD network component with the least network efficiency loss. It can support the overlay network through BGP routing and support tunnel mode when deployed across the equipment room.
+
+ Please note that you can choose to use different Docker networks. ETCD is not the only network solution supported by Submarine.
+
+ You need to select at least three servers as the running server for ETCD, which will make **Submarine** better fault tolerant and stable.
+
+ Enter the IP array as the ETCD server in the ETCD_HOSTS configuration item. The parameter configuration is generally like this:
+
+ ETCD_HOSTS=(hostIP1 hostIP2 hostIP3). Note that spaces between multiple hostIPs should be separated by spaces.
+
++ **DOCKER_REGISTRY Configuration**
+
+ You can follow the following step to setup your Docker registry. But it is not a hard requirement since you can use a pre-setup Docker registry instead.
+
+ You first need to install an image management repository for the available docker. This image repository is used to store the image files of the various deep learning frameworks you need, and then configure the IP address and port of the mirror repository. The parameter configuration is generally the same :
+
+ DOCKER_REGISTRY="10.120.196.232:5000"
+
++ **DOWNLOAD_SERVER Configuration**
+
+ By default, **submarine-installer** downloads all dependencies directly from the network (eg GCC, Docker, Nvidia drivers, etc.), which often takes a lot of time and cannot be used in environments where some servers cannot connect to the Internet. Deployment, so we built the HTTP download service in **submarine-installer**, you only need to run **submarine-installer** on a server that can connect to the Internet, you can download the dependencies for all other servers, you only need Follow these configurations:
+
+ 1. First, you need to configure `DOWNLOAD_SERVER_IP` as a server IP address that can connect to the Internet, and configure `DOWNLOAD_SERVER_PORT` as a port that is not very common.
+ 2. After running the `submarine-installer/install.sh` command on the server where `DOWNLOAD_SERVER_IP` is located, select the `[start download server]` menu item in the installation interface. **submarine-installer** will download all the dependencies of the deployment to the server. In the `submarine-installer/downloads` directory, start an HTTP download service with the `python -m SimpleHTTPServer ${DOWNLOAD_SERVER_PORT}` command. Do not close the **submarine-installer** running on this server.
+ 3. When you run the `submarine-installer/install.sh` command on other servers and follow the `[install component]` menu in the installation interface to install each component in turn, it will automatically download the dependencies from the server where `DOWNLOAD_SERVER_IP` is located for installation and deployment. .
+ 4. **DOWNLOAD_SERVER** Another useful thing is that you can manually download the dependencies by hand, put them in the `submarine-installer/downloads` directory of one of the servers, and then open `[start download server]`, so that you can The cluster provides the ability to deploy offline deployments.
+
++ **YARN_CONTAINER_EXECUTOR_PATH Configuration**
+
+ You can get container-executor binary from either binary release package or build from source.
+ You need to fill in the full path of the container-executor file in the `YARN_CONTAINER_EXECUTOR_PATH` configuration item.
+
++ **YARN_HIERARCHY Configuration**
+
+ Please keep the same configuration as `yarn.nodemanager.linux-container-executor.cgroups.hierarchy` in the `yarn-site.xml` configuration file of the YARN cluster you are using. If this is not configured in `yarn-site.xml`, Then the default is `/hadoop-yarn`.
+
++ **YARN_NODEMANAGER_LOCAL_DIRS Configuration**
+
+ Please keep the same configuration as `yarn.nodemanager.local-dirs` in the `yarn-site.xml` configuration file of the YARN cluster you are using.
+
++ **YARN_NODEMANAGER_LOG_DIRS Configuration**
+
+ Please keep the same configuration as `yarn.nodemanager.log-dirs` in the `yarn-site.xml` configuration file of the YARN cluster you are using.
+
+## Instructions for use
+
+**submarine-installer** is completely written in shell script. It does not need to install any deployment tools such as ansible. It avoids different server management specifications of different company users and causes the program to be uncommon. For example, some computer rooms do not allow ROOT users to directly remotely through SHELL. Server operation, etc.
+
+The deployment process of **submarine-installer** is completely performed by selecting the operation in the menu. It avoids misoperations. You can also install, uninstall, and start any component in each step through various menu items. And the various components are stopped, and the flexibility is very good. After some components have problems, the system can also be diagnosed and repaired by **submarine-installer**.
+
+**submarine-installer** The log information is displayed on the screen during the deployment process. The log information has three font colors:
+
++ Red font color: Indicates that the component installation has an error and the deployment has terminated.
+
++ Green text color: The component is installed properly and the deployment is working properly.
+
++ Blue text color: You need to manually enter the command in another SHELL terminal according to the prompt information. Generally, modify the operating system kernel configuration operation, and follow the prompt information to operate it.
+
+**Start submarine-installer**
+
+Run the `submarine-installer/install.sh` command to start. The deployment program first detects the IP address of the network card in the server. If the server has multiple network cards or multiple IP addresses configured, it will be displayed in the form of a list. Select the one you actually use. IP address.
+
+**submarine-installer** Menu description:
+
+
+
+## Deployment instructions
+
+The deployment process is as follows:
+
+1. Refer to the configuration instructions to configure the `install.conf` file based on your server usage.
+
+2. Copy the entire **submarine-installer** folder to all server nodes
+
+3. First in the server configured as **DOWNLOAD_SERVER**
+
+ + Run the `submarine-installer/install.sh` command
+
+ + Select the `[start download server]` menu item in the installation interface, and wait for the download of each dependency package to start the HTTP service.
+
+4. **In other servers that need to be deployed**
+
+ Run the `submarine-installer/install.sh` command to display the following menu in the main menu **[Main menu]**:
+
+ + prepare system environment
+ + install component
+ + uninstall component
+ + start component
+ + stop component
+ + start download server
+
+5. **prepare system environment**
+
+ - **prepare operation system**
+
+ Check the operating system and version of the deployment server;
+
+ - **prepare operation system kernel**
+
+ Display the prompt information of the operation command of the operating system kernel update, and automatically update the kernel version according to your choice;
+
+ - **prepare GCC version**
+
+ Display the prompt information of the operation command of the current GCC version kernel update in the operating system and whether to automatically update the GCC version according to your choice;
+
+ - **check GPU**
+
+ Check if the server can detect the GPU graphics card;
+
+ - **prepare user&group**
+
+ Display the prompts for adding user and user group operation commands for hadoop and docker. You need to check whether there are any required users and user groups in the server according to the prompt information.
+
+ - **prepare nvidia environment**
+
+ Automatically update the operating system kernel and header files, and automatically install `epel-release` and `dkms`;
+
+ Display the prompt information for modifying the operation command of the system kernel parameter configuration, you need to open another terminal according to the command sequence;
+
+6. **install component**
+
+ - **install etcd**
+
+ Download the bin file for etcd and install it in the `/usr/bin` directory;
+
+ Generate the `etcd.service` file according to the **ETCD_HOSTS** configuration item and install it into the `/etc/systemd/system/` directory.
+
+ - **install docker**
+
+ Download docker's RPM package for local installation;
+
+ Generate the `daemon.json` configuration file and install it into the `/etc/docker/` directory.
+
+ Generate the `docker.service` configuration file and install it into the `/etc/systemd/system/` directory.
+
+ - **install calico network**
+
+ Download the `calico`, `calicoctl`, and `calico-ipam` files and install them in the `/usr/bin` directory.
+
+ Generate the `calicoctl.cfg` configuration file and install it into the `/etc/calico/` directory.
+
+ Generate the `calico-node.service` configuration file and install it into the `/etc/systemd/system/` directory.
+
+ After the installation is complete, the calico network will be automatically created in the container according to the **CALICO_NETWORK_NAME** configuration item, and two Docker containers will be created automatically to check whether the two containers can even ping each other.
+
+ - **install nvidia driver**
+
+ Download the `nvidia-detect` file to detect the graphics card version in the server;Download the `nvidia-detect` file to detect the graphics card version in the server;
+
+ Download the Nvidia graphics driver installation package according to the graphics card version number;
+
+ Check if the Nouveau is disabled in this server. If the installation is not stopped, you need to execute the **[prepare nvidia environment]** submenu item in the **[prepare system environment]** menu and follow the prompts.
+
+ If Nouveau has been disabled in this server, it will be installed locally;
+
+ - **install nvidia docker**
+
+ Download the nvidia-docker RPM installation package and install it;
+
+ Display the command prompt information to detect whether nvidia-docker is available. You need to open another terminal to execute according to the command sequence.
+
+ - **install yarn container-executor**
+
+ Copy the `container-executor` file to the `/etc/yarn/sbin/Linux-amd64-64/` directory according to the **YARN_CONTAINER_EXECUTOR_PATH** configuration item;
+
+ Generate the `container-executor.cfg` file according to the configuration and copy it to the `/etc/yarn/sbin/etc/hadoop/` directory.
+
+ - **install submarine autorun script**
+
+ Copy the submarine.sh file to the `/etc/rc.d/init.d/` directory;
+
+ Add `/etc/rc.d/init.d/submarine.sh` to the `/etc/rc.d/rc.local` system self-starting file;
+
+7. uninstall component
+
+ Delete the BIN file and configuration file of the specified component, not in the retelling
+
+ - uninstall etcd
+ - uninstall docker
+ - uninstall calico network
+ - uninstall nvidia driver
+ - uninstall nvidia docker
+ - uninstall yarn container-executor
+ - uninstall submarine autorun script
+
+8. start component
+
+ Restart the specified component, not repeat
+
+ - start etcd
+ - start docker
+ - start calico network
+
+9. stop component
+
+ Stop specifying component, not repeating
+
+ - stop etcd
+ - stop docker
+ - stop calico network
+
+10. start download server
+
+ This operation can only be performed on the server where the **DOWNLOAD_SERVER_IP** configuration item is located;
+
diff --git a/dev-support/submarine-installer/assets/submarine-installer.gif b/dev-support/submarine-installer/assets/submarine-installer.gif
new file mode 100644
index 0000000000000000000000000000000000000000..56b3b690f0ad4fd4f4d21c461bee6e1714070fbf
Binary files /dev/null and b/dev-support/submarine-installer/assets/submarine-installer.gif differ
diff --git a/dev-support/submarine-installer/install.conf b/dev-support/submarine-installer/install.conf
new file mode 100644
index 0000000000000000000000000000000000000000..69a7dbc46771696e48e43626a723c58f29f019a1
--- /dev/null
+++ b/dev-support/submarine-installer/install.conf
@@ -0,0 +1,181 @@
+#!/usr/bin/env bash
+# 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.
+
+################################ DOWNLOAD CONFIGURATION ####################################################
+# Start the http download service on the specified server,
+# Will download all the dependencies in the http server,
+# Run the install script on other servers.
+# Automatically download dependencies from http,
+# Solve the problem that all servers are slow to download online.
+# At the same time, you can also manually download the dependencies to the downloads directory.
+# Offline installation of the system
+# The host ip on which download service is started.
+DOWNLOAD_SERVER_IP="10.196.69.175"
+DOWNLOAD_SERVER_PORT="19000"
+
+################################ DNS CONFIGURATION #################################################
+# The default DNS ip for the cluster
+LOCAL_DNS_HOST="172.17.0.9" # /etc/resolv.conf
+# see YARN_REGISTRY_DNS_HOST
+
+# determine whether install an security yarn ,value is "true" or "false",default is "true"
+YARN_SECURITY="true"
+
+################################# YARN CONFIGURATION #############################################
+# The resourcemanager hosts. For example, YARN_RESOURCE_MANAGER_HOSTS=(hostname1 hostname2)
+YARN_RESOURCE_MANAGER_HOSTS=()
+# The hosts should not install nodemanager. Multiple hosts should be split by spaces. For example, YARN_NODE_MANAGER_EXCLUDE_HOSTS=(hostname1 hostname2)
+YARN_NODE_MANAGER_EXCLUDE_HOSTS=()
+# hadoop.registry.dns.bind-port & hadoop.registry.dns.bind-address in yarn-site.xml
+YARN_REGISTRY_DNS_HOST="" # yarn registry dns host
+YARN_REGISTRY_DNS_HOST_PORT="53"
+YARN_TIMELINE_HOST="" # timeline-v1.5 & v2.0
+YARN_JOB_HISTORY_HOST=""
+YARN_SPARK_HISTORY_HOST=""
+
+# Kerberos realm used in core-site.xml
+LOCAL_REALM=""
+# The namenode hosts. For example, HDFS_NAMENODE_HOSTS=(hostname1 hostname2)
+HDFS_NAMENODE_HOSTS=()
+
+# fs.defaultFS in core-site.xml. For example, FS_DEFAULTFS="hdfs://machine-learning"
+FS_DEFAULTFS=""
+
+# local.cluster-id in yarn-site.xml
+LOCAL_CLUSTER_ID="ml-yarn"
+
+# yarn.app.mapreduce.am.staging-dir in mapred-site.xml
+YARN_APP_MAPREDUCE_AM_STAGING_DIR="/tmp/ml-yarn-staging"
+
+# yarn container-executor config
+# How to compile container-executor:
+# Go to the hadoop/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager
+# path and enter the command: `mvn package -Pnative -DskipTests`
+# Only the nodemanager is compiled. The path of the compiled container-executor is:
+# ./target/native/target/usr/local/bin/container-executor
+YARN_CONTAINER_EXECUTOR_PATH="/etc/yarn/sbin/Linux-amd64-64/container-executor"
+
+# Keep the same configuration as 'yarn.nodemanager.linux-container-executor.cgroups.hierarchy'
+# in yarn-site.xml, default '/hadoop-yarn'
+YARN_HIERARCHY="/hadoop-yarn"
+
+# The home paths for container dir
+YARN_NODEMANAGER_LOCAL_HOME_PATHS="/home/hadoop/disk/1/yarn,/home/hadoop/disk/2/yarn,/home/hadoop/disk/3/yarn"
+
+# Keep the same configuration as 'yarn.nodemanager.local-dirs' in yarn-site.xml
+YARN_NODEMANAGER_LOCAL_DIRS="/home/hadoop/disk/1/yarn/local,/home/hadoop/disk/2/yarn/local,/home/hadoop/disk/3/yarn/local"
+
+# Keep the same configuration as 'yarn.nodemanager.log-dirs' in yarn-site.xml
+YARN_NODEMANAGER_LOG_DIRS="/home/hadoop/disk/1/yarn/logs,/home/hadoop/disk/2/yarn/logs,/home/hadoop/disk/3/yarn/logs"
+
+# Create '/app-logs' path on hdfs, Owner is 'yarn', group is 'hadoop',
+# and 'hadoop' group needs to include 'hdfs, yarn, mapred' yarn-site.xml users, etc.
+# `yarn.nodemanager.remote-app-log-dir` in yarn-site.xml
+YARN_AGGREGATED_LOG_DIR="/ml-app-logs"
+
+# time line v1.5 store path on hdfs
+YARN_TIMELINE_FS_STORE_DIR="/tmp/ml-entity-file-history"
+
+# hbase client
+YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE="file:/home/hadoop/hbase-current/conf/hbase-site.xml"
+
+# yarn.resourcemanager.zk-address in yarn-site.xml
+# hadoop.registry.zk.quorum in core-site.xml. For Example, YARN_ZK_ADDRESS="zookeeperHost1:2181,zookeeperHost2:2181,zookeeperHost3:2181"
+YARN_ZK_ADDRESS=""
+
+# yarn.timeline-service.leveldb-state-store.path in yarn-site.xml
+YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH="/home/hadoop/timeline"
+
+# yarn.nodemanager.recovery.dir in yarn-site.xml
+YARN_NODEMANAGER_RECOVERY_DIR="/home/hadoop/yarn/yarn-nm-recovery"
+
+# yarn.nodemanager.runtime.linux.docker.default-container-network in yarn-site.xml
+YARN_DOCKER_CONTAINER_DEFAULT_NETWORK=calico-network
+
+# docker.allowed-container-networks in yarn-site.xml and container-executor.cfg
+YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS=host,none,bridge,calico-network
+
+YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH="/home/hadoop/hosts/yarn_exclude"
+
+YARN_GC_LOG_DIR="/home/hadoop/yarn/gclog"
+YARN_PID_DIR="/home/hadoop/yarn/pid"
+YARN_LOG_DIR="/home/hadoop/yarn/log"
+
+################################### YARN-kerberos CONFIGURATION ##############################################
+# Kerberos authentication to create some necessary hdfs paths
+HADOOP_KEYTAB_LOCATION=""
+HADOOP_PRINCIPAL=""
+
+MAPRED_KEYTAB_LOCATION="/home/hadoop/yarn/conf/mapred.service.keytab"
+
+# yarn.timeline-service.keytab in yarn-site.xml
+YARN_KEYTAB_LOCATION="/home/hadoop/yarn/conf/yarn.service.keytab"
+
+HTTP_KEYTAB_LOCATION="/home/hadoop/yarn/conf/http.service.keytab"
+
+################################### JAVA_HOME CONFIGURATION ##############################################
+JAVA_VERSION=jdk1.8.0_152
+JAVA_TARBALL=${JAVA_VERSION}.tgz
+JAVA_HOME=/home/hadoop/java-current
+
+################################### YARN-hadoop CONFIGURATION ##############################################
+HADOOP_SETUP_USER="hadoop"
+HADOOP_VERSION="hadoop-3.3.0-SNAPSHOT"
+HADOOP_TARBALL="${HADOOP_VERSION}.tar.gz"
+HADOOP_HOME="/home/hadoop/hadoop-current"
+
+# hadoop.http.authentication.signature.secret.file in core-site.xml
+HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE="/home/hadoop/yarn/conf/http-secret"
+
+################################# YARN-hbase CONFIGURATION ##############################################
+# copy timeline hbase jar to ${hbase_client]/lib path
+HBASE_HOME="/home/hadoop/hbase-current"
+
+################################ ETCD CONFIGURATION ####################################################
+## etcd host ip list
+ETCD_HOSTS=(10.196.69.201 10.196.69.173 10.196.69.174)
+
+ETCD_VERSION="v3.3.9"
+ETCD_TAR_GZ="etcd-${ETCD_VERSION}-linux-amd64.tar.gz"
+ETCD_DOWNLOAD_URL="https://github.com/etcd-io/etcd/releases/download/${ETCD_VERSION}/${ETCD_TAR_GZ}"
+
+################################## CALICO CONFIGURATION ##########################################
+CALICO_IPV4POOL_CIDR="192.20.0.0"
+CALICO_NETWORK_NAME="calico-network"
+CALICO_DOWNLOAD_URL="https://github.com/projectcalico/cni-plugin/releases/download/v1.11.7/calico"
+CALICO_IPAM_DOWNLOAD_URL="https://github.com/projectcalico/cni-plugin/releases/download/v1.11.7/calico-ipam"
+CALICOCTL_DOWNLOAD_URL="https://github.com/projectcalico/calicoctl/releases/download/v3.2.3/calicoctl"
+
+################################ DOCKER CONFIG SEGMENT ###################################################
+# docker registry ip:port
+DOCKER_REGISTRY="10.120.196.232:5000"
+# /var/lib/docker is used if DOCKER_STORE_PATH not specified
+DOCKER_STORE_PATH=
+
+##### System component download url address, Generally do not need to be modified #####
+DOCKER_REPO="https://download.docker.com/linux/centos/7/x86_64/stable/Packages/"
+DOCKER_VERSION="docker-ce"
+DOCKER_VERSION_NUM="18.06.1.ce"
+DOCKER_ENGINE_RPM="${DOCKER_VERSION}-${DOCKER_VERSION_NUM}-3.el7.x86_64.rpm"
+
+################################# NVIDIA CONFIGURATION #############################################
+NVIDIA_DETECT_URL="http://mirror.rackspace.com/elrepo/elrepo/el7/x86_64/RPMS"
+# NVIDIA_DRIVER_VERSION can be used by download server to decide which version of
+# nvidia driver should be download
+NVIDIA_DRIVER_VERSION=""
+NVIDIA_DOCKER_VERSION="2.0.3"
+NVIDIA_DOCKER_GIT_SNAPSHOT_URL="https://api.github.com/repos/nvidia/"
diff --git a/dev-support/submarine-installer/install.sh b/dev-support/submarine-installer/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..93691b0c3fae79880883f337ce824b932d36e7b6
--- /dev/null
+++ b/dev-support/submarine-installer/install.sh
@@ -0,0 +1,118 @@
+#!/usr/bin/env bash
+# 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.
+# description: submarine install scripts.
+
+ROOT=$(cd "$(dirname "$0")"; pwd)
+SUBMARINE_INSTALLER_VERSION="v0.8.0"
+PACKAGE_DIR=${ROOT}/package
+SCRIPTS_DIR=${ROOT}/scripts
+INSTALL_TEMP_DIR=${ROOT}/temp
+DOWNLOAD_DIR=${ROOT}/downloads
+DATE=`date +%Y%m%d-%H:%M:%S`
+LOG=${ROOT}/logs/install.log.`date +%Y%m%d%H%M%S`
+LOCAL_HOST_IP_LIST=()
+LOCAL_HOST_IP=""
+OPERATING_SYSTEM=""
+DOWNLOAD_HTTP=""
+
+# import shell script
+. ${ROOT}/install.conf
+. ${ROOT}/scripts/calico.sh
+. ${ROOT}/scripts/docker.sh
+. ${ROOT}/scripts/download-server.sh
+. ${ROOT}/scripts/environment.sh
+. ${ROOT}/scripts/etcd.sh
+. ${ROOT}/scripts/yarn.sh
+. ${ROOT}/scripts/yarn_insecure.sh
+. ${ROOT}/scripts/menu.sh
+. ${ROOT}/scripts/nvidia.sh
+. ${ROOT}/scripts/nvidia-docker.sh
+. ${ROOT}/scripts/submarine.sh
+. ${ROOT}/scripts/utils.sh
+
+#================================= Main ========================================
+mkdir $ROOT/logs/ -p
+mkdir $INSTALL_TEMP_DIR -p
+mkdir $DOWNLOAD_DIR -p
+
+source /etc/os-release
+OPERATING_SYSTEM=$ID
+
+get_ip_list
+ipCount=${#LOCAL_HOST_IP_LIST[@]}
+if [[ $ipCount -eq 1 ]]; then
+ LOCAL_HOST_IP=${LOCAL_HOST_IP_LIST[0]}
+else
+ echo -e "Detect the network card IP in the server, \e[31m[${LOCAL_HOST_IP_LIST[@]}]\e[0m"
+ echo -n -e "please enter a valid IP address: "
+
+ read ipInput
+ if ! valid_ip $ipInput; then
+ echo -e "you input \e[31m$ipInput\e[0m address format is incorrect! " | tee -a $LOG
+ exit_install
+ else
+ LOCAL_HOST_IP=$ipInput
+ fi
+fi
+
+echo -n -e "Please confirm whether the IP address of this machine is \e[31m${LOCAL_HOST_IP}\e[0m?[y|n]"
+read myselect
+if [[ "$myselect" != "y" && "$myselect" != "Y" ]]; then
+ exit_install
+fi
+
+check_install_conf
+
+if [[ -n "$DOWNLOAD_SERVER_IP" && -n "$DOWNLOAD_SERVER_PORT" && "$DOWNLOAD_SERVER_IP" != "$LOCAL_HOST_IP" ]]; then
+ DOWNLOAD_HTTP="http://${DOWNLOAD_SERVER_IP}:${DOWNLOAD_SERVER_PORT}"
+fi
+
+check_install_user
+
+# Clean up the installation temporary directory
+rm $INSTALL_TEMP_DIR/* -rf
+
+
+menu_index="0"
+for ((j=1;;j++))
+do
+ menu
+ case "$menu_index" in
+ "0")
+ menu_index="$menu_choice"
+ ;;
+ "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8")
+ # echo "aaaa=$menu_index-$menu_choice"
+ menu_process
+ if [[ $? = 1 ]]; then
+ echo "Press any key to return menu!"
+ read
+ fi
+ ;;
+ "a")
+ exit_install
+ ;;
+ "q")
+ exit_install
+ ;;
+ *)
+ menu_index="0"
+ menu_choice="0"
+ menu
+ ;;
+ esac
+done
diff --git a/dev-support/submarine-installer/package/calico/calico-node.service b/dev-support/submarine-installer/package/calico/calico-node.service
new file mode 100644
index 0000000000000000000000000000000000000000..744c4191f9405ce596d87f50b7c0b92f9ff1ba87
--- /dev/null
+++ b/dev-support/submarine-installer/package/calico/calico-node.service
@@ -0,0 +1,50 @@
+# 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.
+
+[Unit]
+Description=calico node
+After=docker.service
+Requires=docker.service
+
+[Service]
+User=root
+PermissionsStartOnly=true
+ExecStart=/usr/bin/docker run --net=host --privileged --name=calico-node \
+ -e ETCD_ENDPOINTS=ETCD_ENDPOINTS_REPLACE \
+ -e CALICO_LIBNETWORK_ENABLED=true \
+ -e CALICO_NETWORKING_BACKEND=bird \
+ -e CALICO_DISABLE_FILE_LOGGING=true \
+ -e CALICO_IPV4POOL_CIDR=CALICO_IPV4POOL_CIDR_REPLACE/16 \
+ -e CALICO_IPV4POOL_IPIP=always \
+ -e FELIX_DEFAULTENDPOINTTOHOSTACTION=ACCEPT \
+ -e FELIX_IPV6SUPPORT=false \
+ -e FELIX_LOGSEVERITYSCREEN=info \
+ -e FELIX_IPINIPMTU=1440 \
+ -e FELIX_HEALTHENABLED=true \
+ -e IP= \
+ -v /etc/calico/ssl:/etc/calico/ssl \
+ -v /var/run/calico:/var/run/calico \
+ -v /lib/modules:/lib/modules \
+ -v /run/docker/plugins:/run/docker/plugins \
+ -v /var/run/docker.sock:/var/run/docker.sock \
+ -v /var/log/calico:/var/log/calico \
+ calico/node:v2.6.2
+ExecStop=/usr/bin/docker rm -f calico-node
+Restart=always
+RestartSec=10
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/dev-support/submarine-installer/package/calico/calicoctl.cfg b/dev-support/submarine-installer/package/calico/calicoctl.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..44ada867a6265cad2ca1167fbd379e590f480a17
--- /dev/null
+++ b/dev-support/submarine-installer/package/calico/calicoctl.cfg
@@ -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.
+
+apiVersion: v1
+kind: calicoApiConfig
+metadata:
+spec:
+ datastoreType: "etcdv2"
+ etcdEndpoints: ETCD_ENDPOINTS_REPLACE
\ No newline at end of file
diff --git a/dev-support/submarine-installer/package/docker/daemon.json b/dev-support/submarine-installer/package/docker/daemon.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e7e0cf2b379c5fbfebd49d4ec9d3227096bdad6
--- /dev/null
+++ b/dev-support/submarine-installer/package/docker/daemon.json
@@ -0,0 +1,23 @@
+# 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.
+
+{
+ "insecure-registries": ["DOCKER_REGISTRY_REPLACE"],
+ "cluster-store":"CLUSTER_STORE_REPLACE",
+ "cluster-advertise":"LOCAL_HOST_IP_REPLACE:2375",
+ "dns": ["YARN_REGISTRY_DNS_HOST_REPLACE", LOCAL_DNS_HOST_REPLACE],
+ "hosts": ["tcp://LOCAL_HOST_IP_REPLACE:2375","unix:///var/run/docker.sock"]
+}
diff --git a/dev-support/submarine-installer/package/docker/docker.service b/dev-support/submarine-installer/package/docker/docker.service
new file mode 100644
index 0000000000000000000000000000000000000000..f444f995d5791cd16ae78bd0afd78881d399c823
--- /dev/null
+++ b/dev-support/submarine-installer/package/docker/docker.service
@@ -0,0 +1,35 @@
+# 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.
+
+[Unit]
+Description=Docker Application Container Engine
+Documentation=http://docs.docker.io
+
+[Service]
+Environment="PATH=/usr/bin:/bin:/sbin:/usr/bin:/usr/sbin"
+ExecStart=/usr/bin/dockerd --log-level=error
+ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT
+ExecReload=/bin/kill -s HUP $MAINPID
+Restart=on-failure
+RestartSec=5
+LimitNOFILE=infinity
+LimitNPROC=infinity
+LimitCORE=infinity
+Delegate=yes
+KillMode=process
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/dev-support/submarine-installer/package/etcd/etcd.service b/dev-support/submarine-installer/package/etcd/etcd.service
new file mode 100644
index 0000000000000000000000000000000000000000..5a44ce2cfa31434a0eca9e1cc4019638a0a61b7f
--- /dev/null
+++ b/dev-support/submarine-installer/package/etcd/etcd.service
@@ -0,0 +1,40 @@
+# 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.
+
+[Unit]
+Description=etcd
+Documentation=https://github.com/coreos/etcd
+
+[Service]
+Type=notify
+Restart=always
+RestartSec=5s
+LimitNOFILE=40000
+TimeoutStartSec=0
+
+ExecStart=/usr/bin/etcd \
+ --name=ETCD_NODE_NAME_REPLACE \
+ --data-dir=/var/lib/etcd \
+ --listen-client-urls=http://LOCAL_HOST_REPLACE:2379,http://127.0.0.1:2379 \
+ --listen-peer-urls=http://LOCAL_HOST_REPLACE:2380 \
+ --advertise-client-urls=http://LOCAL_HOST_REPLACE:2379 \
+ --initial-advertise-peer-urls=http://LOCAL_HOST_REPLACE:2380 \
+ --initial-cluster=INITIAL_CLUSTER_REPLACE \
+ --initial-cluster-token=etcd-token \
+ --initial-cluster-state=new
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc b/dev-support/submarine-installer/package/hadoop/yarn/etc
new file mode 120000
index 0000000000000000000000000000000000000000..c33e2a06e834e51813321e01fa56b740a19994b2
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc
@@ -0,0 +1 @@
+etc_secure/
\ No newline at end of file
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/capacity-scheduler.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/capacity-scheduler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..742fcd2fecc6d874e6d30369abb1e7c4290f16b2
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/capacity-scheduler.xml
@@ -0,0 +1,131 @@
+
+
+
+
+ yarn.scheduler.capacity.maximum-applications
+
+ 20000
+
+ Maximum number of applications that can be pending and running.
+
+
+
+
+ yarn.scheduler.capacity.maximum-am-resource-percent
+ 0.2
+
+ Maximum percent of resources in the cluster which can be used to run
+ application masters i.e. controls number of concurrent running
+ applications.
+
+
+
+
+ yarn.scheduler.capacity.resource-calculator
+
+ org.apache.hadoop.yarn.util.resource.DominantResourceCalculator
+
+ The ResourceCalculator implementation to be used to compare
+ Resources in the scheduler.
+ The default i.e. DefaultResourceCalculator only uses Memory while
+ DominantResourceCalculator uses dominant-resource to compare
+ multi-dimensional resources such as Memory, CPU etc.
+
+
+
+
+ yarn.scheduler.capacity.root.queues
+ default,dev
+
+ The queues at the this level (root is the root queue).
+
+
+
+
+ yarn.scheduler.capacity.root.default.capacity
+ [memory=100Gi,vcores=20,gpu=1]
+ Default queue target capacity.
+
+
+
+ yarn.scheduler.capacity.root.default.user-limit-factor
+ 1
+
+ The default value is 1
+
+
+
+
+ yarn.scheduler.capacity.root.default.maximum-capacity
+ [memory=200Gi,vcores=40,gpu=2]
+
+ The maximum capacity of the default queue.
+
+
+
+
+ yarn.scheduler.capacity.root.default.user-limit-factor
+ 2.0
+
+
+
+ yarn.scheduler.capacity.root.dev.capacity
+ [memory=100Gi,vcores=20,gpu=1]
+ Default queue target capacity.
+
+
+
+ yarn.scheduler.capacity.root.dev.maximum-capacity
+ [memory=200Gi,vcores=40,gpu=2]
+
+ The maximum capacity of the default queue.
+
+
+
+ yarn.scheduler.capacity.root.default.state
+ RUNNING
+
+ The state of the default queue. State can be one of RUNNING or STOPPED.
+
+
+
+
+ yarn.scheduler.capacity.root.default.acl_submit_applications
+ *
+
+ The ACL of who can submit jobs to the default queue.
+
+
+
+
+ yarn.scheduler.capacity.root.default.acl_administer_queue
+ *
+
+ The ACL of who can administer jobs on the default queue.
+
+
+
+
+ yarn.scheduler.capacity.node-locality-delay
+ 40
+
+ Number of missed scheduling opportunities after which the CapacityScheduler
+ attempts to schedule rack-local containers.
+ Typically this should be set to number of nodes in the cluster, By default is setting
+ approximately number of nodes in one rack which is 40.
+
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/container-executor.cfg b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/container-executor.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..40219eccce973539bb53a992a862a9fa905a40ef
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/container-executor.cfg
@@ -0,0 +1,42 @@
+# 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.
+
+yarn.nodemanager.local-dirs=YARN_NODEMANAGER_LOCAL_DIRS_REPLACE
+yarn.nodemanager.linux-container-executor.group=yarn
+yarn.nodemanager.log-dirs=YARN_NODEMANAGER_LOG_DIRS_REPLACE
+banned.users=root
+allowed.system.users=yarn
+min.user.id=500
+
+[docker]
+module.enabled=true
+docker.binary=/usr/bin/docker
+docker.allowed.capabilities=SYS_CHROOT,MKNOD,SETFCAP,SETPCAP,FSETID,CHOWN,AUDIT_WRITE,SETGID,NET_RAW,FOWNER,SETUID,DAC_OVERRIDE,KILL,NET_BIND_SERVICE,DAC_READ_SEARCH,SYS_PTRACE,SYS_ADMIN
+docker.allowed.networks=bridge,host,none,CALICO_NETWORK_NAME_REPLACE
+docker.allowed.ro-mounts=/etc/group,/etc/passwd,/etc/krb5.conf,YARN_NODEMANAGER_LOCAL_DIRS_REPLACE,regex:^nvidia_driver_.*$
+docker.allowed.rw-mounts=YARN_NODEMANAGER_LOCAL_DIRS_REPLACE,YARN_NODEMANAGER_LOG_DIRS_REPLACE
+docker.privileged-containers.enabled=false
+docker.trusted.registries=local,centos,hortonworks,DOCKER_REGISTRY_REPLACE
+docker.allowed.volume-drivers=nvidia-docker
+docker.allowed.devices=regex:^/dev/nvidia.*$
+docker.allowed.runtimes=nvidia
+
+[gpu]
+module.enabled=true
+
+[cgroups]
+root=/sys/fs/cgroup
+yarn-hierarchy=YARN_HIERARCHY_REPLACE
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/core-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/core-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..72c7f2ed2e711bf7ebad81ad4e94ddce857dd816
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/core-site.xml
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+ fs.defaultFS
+ FS_DEFAULTFS_REPLACE
+ The name of the default file system. Either the literal string "local" or a host:port for NDFS.
+ true
+
+
+
+
+ io.compression.codecs
+ org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec
+
+
+
+ io.compression.codec.lzo.class
+ com.hadoop.compression.lzo.LzoCodec
+
+
+
+
+ webinterface.private.actions
+ false
+ If set to true, the web interfaces of JT and NN may
+ contain
+ actions, such as kill job, delete file, etc., that should
+ not be exposed to public. Enable this option if the interfaces
+ are only reachable by those who have the right authorization.
+
+
+
+
+ hadoop.security.authentication
+ simple
+
+ Set the authentication for the cluster. Valid values are: simple or
+ kerberos.
+
+
+
+
+ hadoop.security.authorization
+ false
+
+ Enable authorization for different protocols.
+
+
+
+
+ hadoop.security.groups.cache.secs
+ 14400
+
+
+
+
+ hadoop.http.filter.initializers
+ org.apache.hadoop.security.AuthenticationFilterInitializer
+
+
+ hadoop.http.authentication.type
+ simple
+
+
+
+ hadoop.http.authentication.token.validity
+ 36000
+
+
+ hadoop.http.authentication.signature.secret.file
+ HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_REPLACE
+
+ The signature secret for signing the authentication tokens.
+ If not set a random secret is generated at startup time.
+ The same secret should be used for JT/NN/DN/TT configurations.
+
+
+
+
+ hadoop.http.authentication.simple.anonymous.allowed
+ true
+
+
+
+ hadoop.tmp.dir
+ /tmp/hadoop-${user.name}
+
+
+
+ io.bytes.per.checksum
+ 4096
+
+
+
+ fs.inmemory.size.mb
+ 200
+
+
+
+ io.file.buffer.size
+ 131072
+
+
+
+ hadoop.proxyuser.mapred.hosts
+ *
+
+
+ hadoop.proxyuser.mapred.groups
+ *
+
+
+
+ hadoop.proxyuser.hive.hosts
+ *
+
+
+ hadoop.proxyuser.hive.groups
+ *
+
+
+
+ hadoop.proxyuser.hadoop.hosts
+ *
+
+
+ hadoop.proxyuser.hadoop.groups
+ *
+
+
+
+ hadoop.proxyuser.yarn.hosts
+ *
+
+
+ hadoop.proxyuser.yarn.groups
+ *
+
+
+
+
+
+ Is the registry enabled in the YARN Resource Manager?
+ If true, the YARN RM will, as needed.
+ create the user and system paths, and purge
+ service records when containers, application attempts
+ and applications complete.
+ If false, the paths must be created by other means,
+ and no automatic cleanup of service records will take place.
+
+ hadoop.registry.rm.enabled
+ false
+
+
+
+
+ A comma separated list of hostname:port pairs defining the
+ zookeeper quorum binding for the registry
+
+ hadoop.registry.zk.quorum
+ YARN_ZK_ADDRESS_REPLACE
+
+
+
+
+ The root zookeeper node for the registry
+
+ hadoop.registry.zk.root
+ /registry
+
+
+
+
+ Zookeeper connection retry count before failing
+
+ hadoop.registry.zk.retry.times
+ 5
+
+
+
+
+
+ hadoop.registry.zk.retry.interval.ms
+ 1000
+
+
+
+
+ Zookeeper session timeout in milliseconds
+
+ hadoop.registry.zk.connection.timeout.ms
+ 15000
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/gpu/yarn-site-gpu.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/gpu/yarn-site-gpu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f76c9b6460fdfb6f44cec56db1af0a6a698ba6f4
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/gpu/yarn-site-gpu.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ yarn.nodemanager.resource-plugins
+ yarn.io/gpu
+
+
+
+ yarn.nodemanager.resource-plugins.gpu.docker-plugin
+ nvidia-docker-v2
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hadoop-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hadoop-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..260b9e451ddbfa9541c1f73da64b2b03aa1928b7
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hadoop-env.sh
@@ -0,0 +1,108 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
+
+# Set Hadoop-specific environment variables here.
+
+# The only required environment variable is JAVA_HOME. All others are
+# optional. When running a distributed configuration it is best to
+# set JAVA_HOME in this file, so that it is correctly defined on
+# remote nodes.
+
+# The java implementation to use.
+#export JAVA_HOME=${JAVA_HOME}
+
+
+###mod
+export JAVA_HOME="JAVA_HOME_REPLACE"
+export HADOOP_HOME="HADOOP_HOME_REPLACE"
+
+#export HADOOP_ROOT_LOGGER=INFO,DRFA
+export HADOOP_SECURITY_LOGGER=INFO,DRFAS
+export HDFS_AUDIT_LOGGER=INFO,DRFAAUDIT
+
+export JSVC_HOME=$HADOOP_HOME/bin
+export HADOOP_CLASSPATH=$HADOOP_HOME/lib/native:$HADOOP_CLASSPATH
+# default heapsize for hadoop daemon
+export HADOOP_HEAPSIZE=5120
+export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true ${HADOOP_OPTS}"
+export HADOOP_LOG_DIR="YARN_LOG_DIR_REPLACE"
+export HADOOP_SECURE_DN_LOG_DIR=$HADOOP_LOG_DIR
+export HADOOP_PID_DIR="YARN_PID_DIR_REPLACE"
+export HADOOP_SECURE_DN_PID_DIR=$HADOOP_PID_DIR
+
+export HADOOP_NAMENODE_USER=hdfs
+export HADOOP_DATANODE_USER=hdfs
+export HADOOP_SECURE_DN_USER=hdfs
+
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+export NAMENODE_JVM_OPTS="-Dcom.netease.appname=NameNode -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/namenode.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx71680m -Xms71680m -Xmn20480m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+export DATANODE_JVM_OPTS="-Dcom.netease.appname=DataNode -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/datanode.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx10240m -Xms10240m -Xmn2048m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+###mod
+
+
+# The jsvc implementation to use. Jsvc is required to run secure datanodes.
+#export JSVC_HOME=${JSVC_HOME}
+
+export HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-"/etc/hadoop"}
+
+# Extra Java CLASSPATH elements. Automatically insert capacity-scheduler.
+for f in $HADOOP_HOME/contrib/capacity-scheduler/*.jar; do
+ if [ "$HADOOP_CLASSPATH" ]; then
+ export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$f
+ else
+ export HADOOP_CLASSPATH=$f
+ fi
+done
+
+# The maximum amount of heap to use, in MB. Default is 1000.
+#export HADOOP_HEAPSIZE=
+#export HADOOP_NAMENODE_INIT_HEAPSIZE=""
+
+# Extra Java runtime options. Empty by default.
+# export HADOOP_OPTS="$HADOOP_OPTS -Djava.net.preferIPv4Stack=true"
+
+# Command specific options appended to HADOOP_OPTS when specified
+export HADOOP_NAMENODE_OPTS="$NAMENODE_JVM_OPTS -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_NAMENODE_OPTS"
+export HADOOP_DATANODE_OPTS="$DATANODE_JVM_OPTS -Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
+
+export HADOOP_SECONDARYNAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_SECONDARYNAMENODE_OPTS"
+
+# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
+#export HADOOP_CLIENT_OPTS="-Xmx512m $HADOOP_CLIENT_OPTS"
+#export HADOOP_CLIENT_OPTS="-Xmx512m $HADOOP_CLIENT_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=6002"
+#HADOOP_JAVA_PLATFORM_OPTS="-XX:-UsePerfData $HADOOP_JAVA_PLATFORM_OPTS"
+
+# On secure datanodes, user to run the datanode as after dropping privileges
+#export HADOOP_SECURE_DN_USER=${HADOOP_SECURE_DN_USER}
+
+# Where log files are stored. $HADOOP_HOME/logs by default.
+#export HADOOP_LOG_DIR=${HADOOP_LOG_DIR}/$USER
+
+# Where log files are stored in the secure data environment.
+#export HADOOP_SECURE_DN_LOG_DIR=${HADOOP_LOG_DIR}/${HADOOP_HDFS_USER}
+
+# The directory where pid files are stored. /tmp by default.
+# NOTE: this should be set to a directory that can only be written to by
+# the user that will run the hadoop daemons. Otherwise there is the
+# potential for a symlink attack.
+#export HADOOP_PID_DIR=${HADOOP_PID_DIR}
+#export HADOOP_SECURE_DN_PID_DIR=${HADOOP_PID_DIR}
+
+# A string representing this instance of hadoop. $USER by default.
+export HADOOP_IDENT_STRING=$USER
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hdfs-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hdfs-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..e5dfce6fac61d79fa32ab70fc2d57c424afe400a
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/hdfs-site.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ local.hostname.nn1
+ HDFS_NAMENODE_HOSTS1_REPLACE
+
+
+ local.hostname.nn2
+ HDFS_NAMENODE_HOSTS2_REPLACE
+
+
+
+ dfs.ha.namenodes.LOCAL_REALM_REPLACE
+ nn1,nn2
+
+
+
+ dfs.namenode.rpc-address.LOCAL_REALM_REPLACE.nn1
+ ${local.hostname.nn1}:8020
+
+
+ dfs.namenode.rpc-address.LOCAL_REALM_REPLACE.nn2
+ ${local.hostname.nn2}:8020
+
+
+
+ dfs.nameservices
+ LOCAL_REALM_REPLACE
+
+
+
+ dfs.client.failover.proxy.provider.LOCAL_REALM_REPLACE
+ org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
+
+
+
+
+ fs.permissions.umask-mode
+ 027
+
+
+
+ dfs.blocksize
+ 268435456
+
+
+
+ dfs.client.read.shortcircuit
+ true
+
+
+
+ dfs.client.read.shortcircuit.streams.cache.size
+ 1024
+
+
+
+ dfs.client.read.shortcircuit.streams.cache.size.expiry.ms
+ 300000
+
+
+
+ dfs.domain.socket.path
+ /var/lib/hadoop-hdfs/dn_socket
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..84bee0b3d3fd300bce995d53df442dce7c2cb8a1
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-env.sh
@@ -0,0 +1,47 @@
+# 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.
+
+##
+## THIS FILE ACTS AS AN OVERRIDE FOR hadoop-env.sh FOR ALL
+## WORK DONE BY THE mapred AND RELATED COMMANDS.
+##
+## Precedence rules:
+##
+## mapred-env.sh > hadoop-env.sh > hard-coded defaults
+##
+## MAPRED_xyz > HADOOP_xyz > hard-coded defaults
+##
+
+###
+# Job History Server specific parameters
+###
+
+# Specify the max heapsize for the JobHistoryServer. If no units are
+# given, it will be assumed to be in MB.
+# This value will be overridden by an Xmx setting specified in HADOOP_OPTS,
+# and/or MAPRED_HISTORYSERVER_OPTS.
+# Default is the same as HADOOP_HEAPSIZE_MAX.
+#export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=5120
+
+# Specify the JVM options to be used when starting the HistoryServer.
+# These options will be appended to the options specified as HADOOP_OPTS
+# and therefore may override any similar flags set in HADOOP_OPTS
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+export MAPRED_HISTORYSERVER_OPTS="-server -Xmx5g -Xms5g -Xmn2g -XX:SurvivorRatio=4 -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -Xloggc:${GC_LOG_DIR}/rm.gc.log-${GC_LOG_DATE}"
+
+# Specify the log4j settings for the JobHistoryServer
+# Java property: hadoop.root.logger
+#export HADOOP_JHS_LOGGER=INFO,RFA
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..19c74336194601f415ad1f113c531302af6abe99
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/mapred-site.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+ mapreduce.framework.name
+ yarn
+
+
+
+ yarn.app.mapreduce.am.staging-dir
+ YARN_APP_MAPREDUCE_AM_STAGING_DIR_REPLACE
+
+
+
+
+ mapreduce.jobhistory.address
+ YARN_JOB_HISTORY_HOST_REPLACE:10020
+
+
+ mapreduce.jobhistory.webapp.address
+ YARN_JOB_HISTORY_HOST_REPLACE:19888
+
+
+
+
+ yarn.app.mapreduce.am.resource.mb
+ 1536
+
+
+ mapreduce.map.memory.mb
+ 1024
+
+
+ mapreduce.reduce.memory.mb
+ 1536
+
+
+ mapreduce.map.java.opts
+ -Xmx820M
+
+
+
+ mapreduce.reduce.java.opts
+ -Xmx1228M
+
+
+ yarn.app.mapreduce.am.command-opts
+ -Xmx1228M
+
+
+
+
+
+ io.sort.factor
+ 100
+
+
+ io.sort.mb
+ 200
+
+
+
+
+ mapreduce.map.speculative
+ false
+
+
+ mapreduce.reduce.speculative
+ false
+
+
+
+
+ mapreduce.map.output.compress
+ true
+
+
+ mapreduce.map.output.compress.codec
+ com.hadoop.compression.lzo.LzoCodec
+
+
+
+ yarn.app.mapreduce.am.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+ mapreduce.map.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+ mapreduce.reduce.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+
+ mapreduce.job.hdfs-servers
+ FS_DEFAULTFS_REPLACE
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/resource-types.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/resource-types.xml
new file mode 100755
index 0000000000000000000000000000000000000000..54ea7dcf6d678fd47e45ab86ab5a4a00c2c65eb3
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/resource-types.xml
@@ -0,0 +1,6 @@
+
+
+ yarn.resource-types
+ yarn.io/gpu
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..41c27e15110af913dc2cba9354a335731d5e3a07
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-env.sh
@@ -0,0 +1,127 @@
+# 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.
+
+
+###mod
+export YARN_ROOT_LOGGER=INFO,DRFA
+#export YARN_ROOT_LOGGER=DEBUG,DRFA
+export YARN_LOG_DIR=$HADOOP_LOG_DIR
+export YARN_PID_DIR=$HADOOP_PID_DIR
+
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+#export RESOURCEMANAGER_JVM_OPTS="-Dcom.netease.appname=ResourceManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/resourcemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx20480m -Xms20480m -Xmn5120m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+export RESOURCEMANAGER_JVM_OPTS="-Dcom.netease.appname=ResourceManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/resourcemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6001"
+export NODEMANAGER_JVM_OPTS="-Dcom.netease.appname=NodeManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/nodemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx5120m -Xms5120m -Xmn1024m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+#export NODEMANAGER_JVM_OPTS="-Dcom.netease.appname=NodeManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/nodemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=6001"
+###mod
+#export YARN_TIMELINESERVER_OPTS="-Dcom.netease.appname=TimelineServer -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/timelineserver.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6001"
+#export YARN_TIMELINEREADER_OPTS="-Dcom.netease.appname=TimelineReaderServer -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/timelineserver.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=6001"
+
+# User for YARN daemons
+export HADOOP_YARN_USER=${HADOOP_YARN_USER:-yarn}
+
+# resolve links - $0 may be a softlink
+export YARN_CONF_DIR="${YARN_CONF_DIR:-$HADOOP_YARN_HOME/etc/hadoop}"
+
+# some Java parameters
+# export JAVA_HOME=/home/y/libexec/jdk1.6.0/
+if [ "$JAVA_HOME" != "" ]; then
+ #echo "run java in $JAVA_HOME"
+ JAVA_HOME=$JAVA_HOME
+fi
+
+if [ "$JAVA_HOME" = "" ]; then
+ echo "Error: JAVA_HOME is not set."
+ exit 1
+fi
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_HEAP_MAX=-Xmx1000m
+
+# For setting YARN specific HEAP sizes please use this
+# Parameter and set appropriately
+# YARN_HEAPSIZE=1000
+
+# check envvars which might override default args
+if [ "$YARN_HEAPSIZE" != "" ]; then
+ JAVA_HEAP_MAX="-Xmx""$YARN_HEAPSIZE""m"
+fi
+
+# Resource Manager specific parameters
+
+# Specify the max Heapsize for the ResourceManager using a numerical value
+# in the scale of MB. For example, to specify an jvm option of -Xmx1000m, set
+# the value to 1000.
+# This value will be overridden by an Xmx setting specified in either YARN_OPTS
+# and/or YARN_RESOURCEMANAGER_OPTS.
+# If not specified, the default value will be picked from either YARN_HEAPMAX
+# or JAVA_HEAP_MAX with YARN_HEAPMAX as the preferred option of the two.
+#export YARN_RESOURCEMANAGER_HEAPSIZE=1000
+
+# Specify the JVM options to be used when starting the ResourceManager.
+# These options will be appended to the options specified as YARN_OPTS
+# and therefore may override any similar flags set in YARN_OPTS
+export YARN_RESOURCEMANAGER_OPTS="$RESOURCEMANAGER_JVM_OPTS"
+
+# Node Manager specific parameters
+
+# Specify the max Heapsize for the NodeManager using a numerical value
+# in the scale of MB. For example, to specify an jvm option of -Xmx1000m, set
+# the value to 1000.
+# This value will be overridden by an Xmx setting specified in either YARN_OPTS
+# and/or YARN_NODEMANAGER_OPTS.
+# If not specified, the default value will be picked from either YARN_HEAPMAX
+# or JAVA_HEAP_MAX with YARN_HEAPMAX as the preferred option of the two.
+#export YARN_NODEMANAGER_HEAPSIZE=1000
+
+# Specify the JVM options to be used when starting the NodeManager.
+# These options will be appended to the options specified as YARN_OPTS
+# and therefore may override any similar flags set in YARN_OPTS
+export YARN_NODEMANAGER_OPTS="$NODEMANAGER_JVM_OPTS"
+
+# so that filenames w/ spaces are handled correctly in loops below
+IFS=
+
+
+# default log directory & file
+if [ "$YARN_LOG_DIR" = "" ]; then
+ YARN_LOG_DIR="$HADOOP_YARN_HOME/logs"
+fi
+if [ "$YARN_LOGFILE" = "" ]; then
+ YARN_LOGFILE='yarn.log'
+fi
+
+# default policy file for service-level authorization
+if [ "$YARN_POLICYFILE" = "" ]; then
+ YARN_POLICYFILE="hadoop-policy.xml"
+fi
+
+# restore ordinary behaviour
+unset IFS
+
+
+YARN_OPTS="$YARN_OPTS -Dhadoop.log.dir=$YARN_LOG_DIR"
+YARN_OPTS="$YARN_OPTS -Dyarn.log.dir=$YARN_LOG_DIR"
+YARN_OPTS="$YARN_OPTS -Dhadoop.log.file=$YARN_LOGFILE"
+YARN_OPTS="$YARN_OPTS -Dyarn.log.file=$YARN_LOGFILE"
+YARN_OPTS="$YARN_OPTS -Dyarn.home.dir=$YARN_COMMON_HOME"
+YARN_OPTS="$YARN_OPTS -Dyarn.id.str=$YARN_IDENT_STRING"
+YARN_OPTS="$YARN_OPTS -Dhadoop.root.logger=${YARN_ROOT_LOGGER:-INFO,console}"
+YARN_OPTS="$YARN_OPTS -Dyarn.root.logger=${YARN_ROOT_LOGGER:-INFO,console}"
+if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
+ YARN_OPTS="$YARN_OPTS -Djava.library.path=$JAVA_LIBRARY_PATH"
+fi
+YARN_OPTS="$YARN_OPTS -Dyarn.policy.file=$YARN_POLICYFILE"
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..ff0fc17cf0a136b99cd21474b75dc80a0aadeac5
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_insecure/hadoop/yarn-site.xml
@@ -0,0 +1,655 @@
+
+
+
+
+
+
+ local.hostname.rm1
+ YARN_RESOURCE_MANAGER_HOSTS1_REPLACE
+
+
+ local.hostname.rm2
+ YARN_RESOURCE_MANAGER_HOSTS2_REPLACE
+
+
+ local.cluster-id
+ LOCAL_CLUSTER_ID_REPLACE
+
+
+
+
+ yarn.resourcemanager.zk-address
+ YARN_ZK_ADDRESS_REPLACE
+
+
+ yarn.resourcemanager.recovery.enabled
+ true
+
+
+ yarn.resourcemanager.store.class
+ org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
+
+
+ yarn.resourcemanager.zk-timeout-ms
+ 90000
+
+
+ yarn.resourcemanager.am.max-attempts
+ 3
+
+
+ yarn.resourcemanager.state-store.max-completed-applications
+ 200
+
+
+
+
+ yarn.resourcemanager.ha.enabled
+ true
+
+
+ yarn.resourcemanager.cluster-id
+ ${local.cluster-id}
+
+
+ yarn.resourcemanager.ha.rm-ids
+ rm1,rm2
+
+
+
+ yarn.resourcemanager.hostname.rm1
+ ${local.hostname.rm1}
+
+
+
+ yarn.resourcemanager.hostname.rm2
+ ${local.hostname.rm2}
+
+
+
+ yarn.resourcemanager.webapp.address.rm1
+ ${local.hostname.rm1}:8088
+
+
+
+ yarn.resourcemanager.webapp.address.rm2
+ ${local.hostname.rm2}:8088
+
+
+
+
+ yarn.nodemanager.aux-services
+ mapreduce_shuffle,spark_shuffle,timeline_collector
+
+
+ yarn.nodemanager.aux-services.mapreduce_shuffle.class
+ org.apache.hadoop.mapred.ShuffleHandler
+
+
+ yarn.nodemanager.aux-services.spark_shuffle.class
+ org.apache.spark.network.yarn.YarnShuffleService
+
+
+ spark.yarn.shuffle.stopOnFailure
+ true
+
+
+ yarn.nodemanager.aux-services.timeline_collector.class
+ org.apache.hadoop.yarn.server.timelineservice.collector.PerNodeTimelineCollectorsAuxService
+
+
+
+
+ yarn.nodemanager.local-dirs
+ YARN_NODEMANAGER_LOCAL_DIRS_REPLACE
+
+
+ yarn.nodemanager.log-dirs
+ YARN_NODEMANAGER_LOG_DIRS_REPLACE
+
+
+
+
+ Where to aggregate logs in hdfs
+ yarn.nodemanager.remote-app-log-dir
+ YARN_AGGREGATED_LOG_DIR_REPLACE
+
+
+ yarn.log-aggregation-enable
+ true
+
+
+ yarn.log-aggregation.retain-seconds
+ 604800
+
+
+ yarn.log-aggregation.retain-check-interval-seconds
+ 86400
+
+
+ yarn.nodemanager.log-aggregation.compression-type
+ gz
+
+
+
+
+
+
+
+
+ yarn.nodemanager.container-executor.class
+ org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor
+
+
+ yarn.nodemanager.linux-container-executor.path
+ /etc/yarn/sbin/Linux-amd64-64/container-executor
+
+
+ yarn.nodemanager.linux-container-executor.group
+ yarn
+
+
+
+
+ Miniumum request grant-able by the RM scheduler
+ yarn.scheduler.minimum-allocation-mb
+ 512
+
+
+ Maximum request grant-able by the RM scheduler
+ yarn.scheduler.maximum-allocation-mb
+ 32768
+
+
+ yarn.scheduler.minimum-allocation-vcores
+ 1
+
+
+ yarn.scheduler.maximum-allocation-vcores
+ 30
+
+
+ yarn.resourcemanager.scheduler.class
+
+ org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
+
+
+
+ yarn.scheduler.increment-allocation-mb
+ 512
+
+
+ yarn.scheduler.fair.allow-undeclared-pools
+ false
+
+
+
+ yarn.client.nodemanager-connect.max-wait-ms
+ 60000
+
+
+
+
+ yarn.resourcemanager.client.thread-count
+ 64
+
+
+ yarn.resourcemanager.resource-tracker.client.thread-count
+ 64
+
+
+ yarn.resourcemanager.scheduler.client.thread-count
+ 64
+
+
+ yarn.nodemanager.container-manager.thread-count
+ 32
+
+
+ yarn.nodemanager.container-metrics.enable
+ true
+ Todo hbase metrics cleanup mechanism
+
+
+
+
+ The minimum space that must be available on a disk for
+ it to be used. This applies to yarn.nodemanager.local-dirs and
+ yarn.nodemanager.log-dirs.
+ yarn.nodemanager.disk-health-checker.min-free-space-per-disk-mb
+ 1000
+
+
+ Defines how often NMs wake up to upload log files.
+ The default value is -1. By default, the logs will be uploaded when
+ the application is finished. By setting this configure, logs can be uploaded
+ periodically when the application is running. The minimum rolling-interval-seconds
+ can be set is 3600.
+
+ yarn.nodemanager.log-aggregation.roll-monitoring-interval-seconds
+ 3600
+
+
+ Enable the node manager to recover after starting
+ yarn.nodemanager.recovery.enabled
+ true
+
+
+ The local filesystem directory in which the node manager will
+ store state when recovery is enabled.
+ yarn.nodemanager.recovery.dir
+ YARN_NODEMANAGER_RECOVERY_DIR_REPLACE
+
+
+
+
+ yarn.nodemanager.resource.memory-mb
+ 204800
+
+
+ yarn.nodemanager.resource.cpu-vcores
+ 40
+
+
+
+ yarn.admin.acl
+ hadoop,yarn
+
+
+ yarn.acl.enable
+ true
+
+
+
+
+ yarn.resourcemanager.nodes.exclude-path
+ YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH_REPLACE
+
+
+ If true, ResourceManager will have proxy-user privileges.
+ Use case: In a secure cluster, YARN requires the user hdfs delegation-tokens to
+ do localization and log-aggregation on behalf of the user. If this is set to true,
+ ResourceManager is able to request new hdfs delegation tokens on behalf of
+ the user. This is needed by long-running-service, because the hdfs tokens
+ will eventually expire and YARN requires new valid tokens to do localization
+ and log-aggregation. Note that to enable this use case, the corresponding
+ HDFS NameNode has to configure ResourceManager as the proxy-user so that
+ ResourceManager can itself ask for new tokens on behalf of the user when
+ tokens are past their max-life-time.
+ yarn.resourcemanager.proxy-user-privileges.enabled
+ true
+
+
+
+
+ yarn.resourcemanager.webapp.delegation-token-auth-filter.enabled
+ false
+
+
+
+ hadoop.http.filter.initializers
+ org.apache.hadoop.security.AuthenticationFilterInitializer
+
+
+ hadoop.http.authentication.type
+ true
+
+
+
+
+ yarn.nodemanager.container.use.serialgc.enable
+ true
+
+
+
+
+ Indicate to clients whether Timeline service is enabled or not.
+ If enabled, the TimelineClient library used by end-users will post entities
+ and events to the Timeline server.
+ yarn.timeline-service.enabled
+ true
+
+
+
+ The setting that controls whether yarn system metrics is
+ published on the timeline server or not by RM.
+ yarn.resourcemanager.system-metrics-publisher.enabled
+ true
+
+
+
+ Indicate to clients whether to query generic application
+ data from timeline history-service or not. If not enabled then application
+ data is queried only from Resource Manager.
+ yarn.timeline-service.generic-application-history.enabled
+ true
+
+
+
+ yarn.timeline-service.http-authentication.type
+ simple
+
+
+
+
+ yarn.timeline-service.hostname
+ YARN_TIMELINE_HOST_REPLACE
+
+
+
+ yarn.timeline-service.hbase.coprocessor.jar.hdfs.location
+ /hbase/coprocessor
+
+
+
+ URL for log aggregation server web service
+ yarn.log.server.web-service.url
+ http://YARN_TIMELINE_HOST_REPLACE:8189/ws/v2/applicationlog
+
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.path
+ YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE
+
+
+
+ yarn.timeline-service.leveldb-state-store.path
+ YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.read-cache-size
+ 104857600
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.start-time-read-cache-size
+ 10000
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.start-time-write-cache-size
+ 10000
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms
+ 300000
+
+
+
+ yarn.timeline-service.recovery.enabled
+ true
+
+
+
+ yarn.timeline-service.state-store-class
+ org.apache.hadoop.yarn.server.timeline.recovery.LeveldbTimelineStateStore
+
+
+
+ yarn.timeline-service.store-class
+ org.apache.hadoop.yarn.server.timeline.EntityGroupFSTimelineStore
+
+
+
+ yarn.timeline-service.ttl-enable
+ true
+
+
+
+ yarn.timeline-service.ttl-ms
+ 2678400000
+
+
+
+
+ yarn.timeline-service.version
+ 2.0f
+
+
+
+ The setting that controls whether yarn system metrics is
+ published on the Timeline service or not by RM And NM.
+ yarn.system-metrics-publisher.enabled
+ true
+
+
+
+ The setting that controls whether yarn container events are
+ published to the timeline service or not by RM. This configuration setting
+ is for ATS V2.
+
+ yarn.rm.system-metrics-publisher.emit-container-events
+ true
+
+
+
+ Optional URL to an hbase-site.xml configuration file to be
+ used to connect to the timeline-service hbase cluster. If empty or not
+ specified, then the HBase configuration will be loaded from the classpath.
+ When specified the values in the specified configuration file will override
+ those from the ones that are present on the classpath.
+
+ yarn.timeline-service.hbase.configuration.file
+ YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE_REPLACE
+
+
+
+
+ yarn.timeline-service.versions
+ 1.5f,2.0f
+
+
+
+ yarn.timeline-service.entity-group-fs-store.active-dir
+ YARN_TIMELINE_FS_STORE_DIR_REPLACE/active
+
+
+
+ yarn.timeline-service.entity-group-fs-store.done-dir
+ YARN_TIMELINE_FS_STORE_DIR_REPLACE/done
+
+
+
+
+ yarn.timeline-service.reader.webapp.address
+ YARN_TIMELINE_HOST_REPLACE:8189
+
+
+
+ yarn.timeline-service.entity-group-fs-store.summary-store
+ org.apache.hadoop.yarn.server.timeline.RollingLevelDBTimelineStore
+
+
+
+ Enable services rest api on ResourceManager.
+ yarn.webapp.api-service.enable
+ true
+
+
+
+ The domain name for Hadoop cluster associated records. As short as possible.
+ hadoop.registry.dns.domain-name
+ ml
+
+
+
+ The DNS functionality is enabled for the cluster. Default is false.
+ hadoop.registry.dns.enabled
+ true
+
+
+ Address associated with the network interface to which the DNS listener should bind.
+ hadoop.registry.dns.bind-address
+ YARN_REGISTRY_DNS_HOST_REPLACE
+
+
+ The port number for the DNS listener. The default port is 5353.
+ If the standard privileged port 53 is used, make sure start the DNS with jsvc support.
+ hadoop.registry.dns.bind-port
+
+ YARN_REGISTRY_DNS_HOST_PORT_REPLACE
+
+
+
+
+ yarn.nodemanager.linux-container-executor.resources-handler.class
+ org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.mount
+ false
+
+
+ yarn.nodemanager.resource.percentage-physical-cpu-limit
+ 80
+
+
+ Whether virtual memory limits will be enforced for containers.
+ yarn.nodemanager.vmem-check-enabled
+ false
+
+
+
+ Whether YARN CGroups memory tracking is enabled.
+ yarn.nodemanager.resource.memory.enabled
+ true
+
+
+
+
+ yarn.nodemanager.runtime.linux.docker.default-container-network
+
+ CALICO_NETWORK_NAME_REPLACE
+
+
+ yarn.nodemanager.runtime.linux.allowed-runtimes
+ default,docker
+
+
+ yarn.nodemanager.runtime.linux.docker.allowed-container-networks
+ host,none,bridge,CALICO_NETWORK_NAME_REPLACE
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.allowed
+ false
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.acl
+
+
+
+ yarn.nodemanager.runtime.linux.docker.capabilities
+ CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE
+
+
+
+
+ yarn.webapp.ui2.enable
+ true
+
+
+
+
+
+ yarn.service.base.path
+ /tmp/.LOCAL_CLUSTER_ID_REPLACE/
+
+
+
+ yarn.nodemanager.address
+ 0.0.0.0:45454
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/capacity-scheduler.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/capacity-scheduler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..742fcd2fecc6d874e6d30369abb1e7c4290f16b2
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/capacity-scheduler.xml
@@ -0,0 +1,131 @@
+
+
+
+
+ yarn.scheduler.capacity.maximum-applications
+
+ 20000
+
+ Maximum number of applications that can be pending and running.
+
+
+
+
+ yarn.scheduler.capacity.maximum-am-resource-percent
+ 0.2
+
+ Maximum percent of resources in the cluster which can be used to run
+ application masters i.e. controls number of concurrent running
+ applications.
+
+
+
+
+ yarn.scheduler.capacity.resource-calculator
+
+ org.apache.hadoop.yarn.util.resource.DominantResourceCalculator
+
+ The ResourceCalculator implementation to be used to compare
+ Resources in the scheduler.
+ The default i.e. DefaultResourceCalculator only uses Memory while
+ DominantResourceCalculator uses dominant-resource to compare
+ multi-dimensional resources such as Memory, CPU etc.
+
+
+
+
+ yarn.scheduler.capacity.root.queues
+ default,dev
+
+ The queues at the this level (root is the root queue).
+
+
+
+
+ yarn.scheduler.capacity.root.default.capacity
+ [memory=100Gi,vcores=20,gpu=1]
+ Default queue target capacity.
+
+
+
+ yarn.scheduler.capacity.root.default.user-limit-factor
+ 1
+
+ The default value is 1
+
+
+
+
+ yarn.scheduler.capacity.root.default.maximum-capacity
+ [memory=200Gi,vcores=40,gpu=2]
+
+ The maximum capacity of the default queue.
+
+
+
+
+ yarn.scheduler.capacity.root.default.user-limit-factor
+ 2.0
+
+
+
+ yarn.scheduler.capacity.root.dev.capacity
+ [memory=100Gi,vcores=20,gpu=1]
+ Default queue target capacity.
+
+
+
+ yarn.scheduler.capacity.root.dev.maximum-capacity
+ [memory=200Gi,vcores=40,gpu=2]
+
+ The maximum capacity of the default queue.
+
+
+
+ yarn.scheduler.capacity.root.default.state
+ RUNNING
+
+ The state of the default queue. State can be one of RUNNING or STOPPED.
+
+
+
+
+ yarn.scheduler.capacity.root.default.acl_submit_applications
+ *
+
+ The ACL of who can submit jobs to the default queue.
+
+
+
+
+ yarn.scheduler.capacity.root.default.acl_administer_queue
+ *
+
+ The ACL of who can administer jobs on the default queue.
+
+
+
+
+ yarn.scheduler.capacity.node-locality-delay
+ 40
+
+ Number of missed scheduling opportunities after which the CapacityScheduler
+ attempts to schedule rack-local containers.
+ Typically this should be set to number of nodes in the cluster, By default is setting
+ approximately number of nodes in one rack which is 40.
+
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/container-executor.cfg b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/container-executor.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..c4bb5ea8493b360ac4145dda3eb93576881be34d
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/container-executor.cfg
@@ -0,0 +1,42 @@
+# 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.
+
+yarn.nodemanager.local-dirs=YARN_NODEMANAGER_LOCAL_DIRS_REPLACE
+yarn.nodemanager.linux-container-executor.group=yarn
+yarn.nodemanager.log-dirs=YARN_NODEMANAGER_LOG_DIRS_REPLACE
+banned.users=root
+allowed.system.users=yarn
+min.user.id=500
+
+[docker]
+module.enabled=true
+docker.binary=/usr/bin/docker
+docker.allowed.capabilities=SYS_CHROOT,MKNOD,SETFCAP,SETPCAP,FSETID,CHOWN,AUDIT_WRITE,SETGID,NET_RAW,FOWNER,SETUID,DAC_OVERRIDE,KILL,NET_BIND_SERVICE,DAC_READ_SEARCH,SYS_PTRACE,SYS_ADMIN
+docker.allowed.networks=YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS_REPLACE
+docker.allowed.ro-mounts=/etc/group,/etc/passwd,/etc/krb5.conf,YARN_NODEMANAGER_LOCAL_DIRS_REPLACE,HADOOP_HOME_REPLACE,regex:^nvidia_driver_.*$
+docker.allowed.rw-mounts=YARN_NODEMANAGER_LOCAL_DIRS_REPLACE,YARN_NODEMANAGER_LOG_DIRS_REPLACE
+docker.privileged-containers.enabled=false
+docker.trusted.registries=local,centos,hortonworks,DOCKER_REGISTRY_REPLACE
+docker.allowed.volume-drivers=nvidia-docker
+docker.allowed.devices=regex:^/dev/nvidia.*$
+docker.allowed.runtimes=nvidia
+
+[gpu]
+module.enabled=true
+
+[cgroups]
+root=/sys/fs/cgroup
+yarn-hierarchy=YARN_HIERARCHY_REPLACE
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/core-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/core-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..27ed6419e08c24008a40ce3331c2a4cbf7ea51d1
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/core-site.xml
@@ -0,0 +1,235 @@
+
+
+
+
+
+
+ local.realm
+ LOCAL_REALM_REPLACE
+
+
+
+
+ fs.defaultFS
+ FS_DEFAULTFS_REPLACE
+ The name of the default file system. Either the literal string "local" or a host:port for NDFS.
+ true
+
+
+
+
+ io.compression.codecs
+ org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec
+
+
+
+ io.compression.codec.lzo.class
+ com.hadoop.compression.lzo.LzoCodec
+
+
+
+
+ webinterface.private.actions
+ false
+ If set to true, the web interfaces of JT and NN may
+ contain
+ actions, such as kill job, delete file, etc., that should
+ not be exposed to public. Enable this option if the interfaces
+ are only reachable by those who have the right authorization.
+
+
+
+
+ hadoop.security.authentication
+ kerberos
+
+ Set the authentication for the cluster. Valid values are: simple or
+ kerberos.
+
+
+
+
+ hadoop.security.authorization
+ true
+
+ Enable authorization for different protocols.
+
+
+
+
+ hadoop.security.groups.cache.secs
+ 14400
+
+
+
+ hadoop.kerberos.kinit.command
+ /usr/bin/kinit
+
+
+
+
+ hadoop.http.filter.initializers
+ org.apache.hadoop.security.AuthenticationFilterInitializer
+
+
+
+ hadoop.http.authentication.type
+ kerberos
+
+
+
+ hadoop.http.authentication.token.validity
+ 36000
+
+
+
+ hadoop.http.authentication.signature.secret.file
+ HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_REPLACE
+
+ The signature secret for signing the authentication tokens.
+ If not set a random secret is generated at startup time.
+ The same secret should be used for JT/NN/DN/TT configurations.
+
+
+
+
+ hadoop.http.authentication.cookie.domain
+ ${local.realm}
+
+
+
+ hadoop.http.authentication.simple.anonymous.allowed
+ true
+
+
+
+ hadoop.http.authentication.kerberos.principal
+ HTTP/_HOST@${local.realm}
+
+
+
+ hadoop.http.authentication.kerberos.keytab
+ HTTP_KEYTAB_LOCATION_REPLACE
+
+
+
+ hadoop.tmp.dir
+ /tmp/hadoop-${user.name}
+
+
+
+ io.bytes.per.checksum
+ 4096
+
+
+
+ fs.inmemory.size.mb
+ 200
+
+
+
+ io.file.buffer.size
+ 131072
+
+
+
+ hadoop.proxyuser.mapred.hosts
+ *
+
+
+ hadoop.proxyuser.mapred.groups
+ *
+
+
+
+ hadoop.proxyuser.hive.hosts
+ *
+
+
+ hadoop.proxyuser.hive.groups
+ *
+
+
+
+ hadoop.proxyuser.hadoop.hosts
+ *
+
+
+ hadoop.proxyuser.hadoop.groups
+ *
+
+
+
+ hadoop.proxyuser.yarn.hosts
+ *
+
+
+ hadoop.proxyuser.yarn.groups
+ *
+
+
+
+
+
+ Is the registry enabled in the YARN Resource Manager?
+ If true, the YARN RM will, as needed.
+ create the user and system paths, and purge
+ service records when containers, application attempts
+ and applications complete.
+ If false, the paths must be created by other means,
+ and no automatic cleanup of service records will take place.
+
+ hadoop.registry.rm.enabled
+ false
+
+
+
+
+ A comma separated list of hostname:port pairs defining the
+ zookeeper quorum binding for the registry
+
+ hadoop.registry.zk.quorum
+ YARN_ZK_ADDRESS_REPLACE
+
+
+
+
+ The root zookeeper node for the registry
+
+ hadoop.registry.zk.root
+ /registry
+
+
+
+
+ Zookeeper connection retry count before failing
+
+ hadoop.registry.zk.retry.times
+ 5
+
+
+
+
+
+ hadoop.registry.zk.retry.interval.ms
+ 1000
+
+
+
+
+ Zookeeper session timeout in milliseconds
+
+ hadoop.registry.zk.connection.timeout.ms
+ 15000
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/gpu/yarn-site-gpu.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/gpu/yarn-site-gpu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f76c9b6460fdfb6f44cec56db1af0a6a698ba6f4
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/gpu/yarn-site-gpu.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ yarn.nodemanager.resource-plugins
+ yarn.io/gpu
+
+
+
+ yarn.nodemanager.resource-plugins.gpu.docker-plugin
+ nvidia-docker-v2
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hadoop-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hadoop-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..260b9e451ddbfa9541c1f73da64b2b03aa1928b7
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hadoop-env.sh
@@ -0,0 +1,108 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
+
+# Set Hadoop-specific environment variables here.
+
+# The only required environment variable is JAVA_HOME. All others are
+# optional. When running a distributed configuration it is best to
+# set JAVA_HOME in this file, so that it is correctly defined on
+# remote nodes.
+
+# The java implementation to use.
+#export JAVA_HOME=${JAVA_HOME}
+
+
+###mod
+export JAVA_HOME="JAVA_HOME_REPLACE"
+export HADOOP_HOME="HADOOP_HOME_REPLACE"
+
+#export HADOOP_ROOT_LOGGER=INFO,DRFA
+export HADOOP_SECURITY_LOGGER=INFO,DRFAS
+export HDFS_AUDIT_LOGGER=INFO,DRFAAUDIT
+
+export JSVC_HOME=$HADOOP_HOME/bin
+export HADOOP_CLASSPATH=$HADOOP_HOME/lib/native:$HADOOP_CLASSPATH
+# default heapsize for hadoop daemon
+export HADOOP_HEAPSIZE=5120
+export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true ${HADOOP_OPTS}"
+export HADOOP_LOG_DIR="YARN_LOG_DIR_REPLACE"
+export HADOOP_SECURE_DN_LOG_DIR=$HADOOP_LOG_DIR
+export HADOOP_PID_DIR="YARN_PID_DIR_REPLACE"
+export HADOOP_SECURE_DN_PID_DIR=$HADOOP_PID_DIR
+
+export HADOOP_NAMENODE_USER=hdfs
+export HADOOP_DATANODE_USER=hdfs
+export HADOOP_SECURE_DN_USER=hdfs
+
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+export NAMENODE_JVM_OPTS="-Dcom.netease.appname=NameNode -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/namenode.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx71680m -Xms71680m -Xmn20480m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+export DATANODE_JVM_OPTS="-Dcom.netease.appname=DataNode -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/datanode.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx10240m -Xms10240m -Xmn2048m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+###mod
+
+
+# The jsvc implementation to use. Jsvc is required to run secure datanodes.
+#export JSVC_HOME=${JSVC_HOME}
+
+export HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-"/etc/hadoop"}
+
+# Extra Java CLASSPATH elements. Automatically insert capacity-scheduler.
+for f in $HADOOP_HOME/contrib/capacity-scheduler/*.jar; do
+ if [ "$HADOOP_CLASSPATH" ]; then
+ export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$f
+ else
+ export HADOOP_CLASSPATH=$f
+ fi
+done
+
+# The maximum amount of heap to use, in MB. Default is 1000.
+#export HADOOP_HEAPSIZE=
+#export HADOOP_NAMENODE_INIT_HEAPSIZE=""
+
+# Extra Java runtime options. Empty by default.
+# export HADOOP_OPTS="$HADOOP_OPTS -Djava.net.preferIPv4Stack=true"
+
+# Command specific options appended to HADOOP_OPTS when specified
+export HADOOP_NAMENODE_OPTS="$NAMENODE_JVM_OPTS -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_NAMENODE_OPTS"
+export HADOOP_DATANODE_OPTS="$DATANODE_JVM_OPTS -Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
+
+export HADOOP_SECONDARYNAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_SECONDARYNAMENODE_OPTS"
+
+# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
+#export HADOOP_CLIENT_OPTS="-Xmx512m $HADOOP_CLIENT_OPTS"
+#export HADOOP_CLIENT_OPTS="-Xmx512m $HADOOP_CLIENT_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=6002"
+#HADOOP_JAVA_PLATFORM_OPTS="-XX:-UsePerfData $HADOOP_JAVA_PLATFORM_OPTS"
+
+# On secure datanodes, user to run the datanode as after dropping privileges
+#export HADOOP_SECURE_DN_USER=${HADOOP_SECURE_DN_USER}
+
+# Where log files are stored. $HADOOP_HOME/logs by default.
+#export HADOOP_LOG_DIR=${HADOOP_LOG_DIR}/$USER
+
+# Where log files are stored in the secure data environment.
+#export HADOOP_SECURE_DN_LOG_DIR=${HADOOP_LOG_DIR}/${HADOOP_HDFS_USER}
+
+# The directory where pid files are stored. /tmp by default.
+# NOTE: this should be set to a directory that can only be written to by
+# the user that will run the hadoop daemons. Otherwise there is the
+# potential for a symlink attack.
+#export HADOOP_PID_DIR=${HADOOP_PID_DIR}
+#export HADOOP_SECURE_DN_PID_DIR=${HADOOP_PID_DIR}
+
+# A string representing this instance of hadoop. $USER by default.
+export HADOOP_IDENT_STRING=$USER
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hdfs-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hdfs-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..e5dfce6fac61d79fa32ab70fc2d57c424afe400a
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/hdfs-site.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ local.hostname.nn1
+ HDFS_NAMENODE_HOSTS1_REPLACE
+
+
+ local.hostname.nn2
+ HDFS_NAMENODE_HOSTS2_REPLACE
+
+
+
+ dfs.ha.namenodes.LOCAL_REALM_REPLACE
+ nn1,nn2
+
+
+
+ dfs.namenode.rpc-address.LOCAL_REALM_REPLACE.nn1
+ ${local.hostname.nn1}:8020
+
+
+ dfs.namenode.rpc-address.LOCAL_REALM_REPLACE.nn2
+ ${local.hostname.nn2}:8020
+
+
+
+ dfs.nameservices
+ LOCAL_REALM_REPLACE
+
+
+
+ dfs.client.failover.proxy.provider.LOCAL_REALM_REPLACE
+ org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
+
+
+
+
+ fs.permissions.umask-mode
+ 027
+
+
+
+ dfs.blocksize
+ 268435456
+
+
+
+ dfs.client.read.shortcircuit
+ true
+
+
+
+ dfs.client.read.shortcircuit.streams.cache.size
+ 1024
+
+
+
+ dfs.client.read.shortcircuit.streams.cache.size.expiry.ms
+ 300000
+
+
+
+ dfs.domain.socket.path
+ /var/lib/hadoop-hdfs/dn_socket
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..84bee0b3d3fd300bce995d53df442dce7c2cb8a1
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-env.sh
@@ -0,0 +1,47 @@
+# 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.
+
+##
+## THIS FILE ACTS AS AN OVERRIDE FOR hadoop-env.sh FOR ALL
+## WORK DONE BY THE mapred AND RELATED COMMANDS.
+##
+## Precedence rules:
+##
+## mapred-env.sh > hadoop-env.sh > hard-coded defaults
+##
+## MAPRED_xyz > HADOOP_xyz > hard-coded defaults
+##
+
+###
+# Job History Server specific parameters
+###
+
+# Specify the max heapsize for the JobHistoryServer. If no units are
+# given, it will be assumed to be in MB.
+# This value will be overridden by an Xmx setting specified in HADOOP_OPTS,
+# and/or MAPRED_HISTORYSERVER_OPTS.
+# Default is the same as HADOOP_HEAPSIZE_MAX.
+#export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=5120
+
+# Specify the JVM options to be used when starting the HistoryServer.
+# These options will be appended to the options specified as HADOOP_OPTS
+# and therefore may override any similar flags set in HADOOP_OPTS
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+export MAPRED_HISTORYSERVER_OPTS="-server -Xmx5g -Xms5g -Xmn2g -XX:SurvivorRatio=4 -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -Xloggc:${GC_LOG_DIR}/rm.gc.log-${GC_LOG_DATE}"
+
+# Specify the log4j settings for the JobHistoryServer
+# Java property: hadoop.root.logger
+#export HADOOP_JHS_LOGGER=INFO,RFA
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..cf03e24460dccc5eb18cac1bea4ab548e980aad3
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/mapred-site.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+ mapreduce.framework.name
+ yarn
+
+
+
+ yarn.app.mapreduce.am.staging-dir
+ YARN_APP_MAPREDUCE_AM_STAGING_DIR_REPLACE
+
+
+
+
+ mapreduce.jobhistory.address
+ YARN_JOB_HISTORY_HOST_REPLACE:10020
+
+
+ mapreduce.jobhistory.webapp.address
+ YARN_JOB_HISTORY_HOST_REPLACE:19888
+
+
+ mapreduce.jobhistory.keytab
+ MAPRED_KEYTAB_LOCATION_REPLACE
+
+
+ mapreduce.jobhistory.principal
+ mapred/_HOST@${local.realm}
+
+
+
+
+ yarn.app.mapreduce.am.resource.mb
+ 1536
+
+
+ mapreduce.map.memory.mb
+ 1024
+
+
+ mapreduce.reduce.memory.mb
+ 1536
+
+
+ mapreduce.map.java.opts
+ -Xmx820M
+
+
+
+ mapreduce.reduce.java.opts
+ -Xmx1228M
+
+
+ yarn.app.mapreduce.am.command-opts
+ -Xmx1228M
+
+
+
+
+
+ io.sort.factor
+ 100
+
+
+ io.sort.mb
+ 200
+
+
+
+
+ mapreduce.map.speculative
+ false
+
+
+ mapreduce.reduce.speculative
+ false
+
+
+
+
+ mapreduce.map.output.compress
+ true
+
+
+ mapreduce.map.output.compress.codec
+ com.hadoop.compression.lzo.LzoCodec
+
+
+
+ yarn.app.mapreduce.am.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+ mapreduce.map.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+ mapreduce.reduce.env
+ HADOOP_MAPRED_HOME=$HADOOP_HOME
+
+
+
+ mapreduce.job.hdfs-servers
+ FS_DEFAULTFS_REPLACE
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/resource-types.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/resource-types.xml
new file mode 100755
index 0000000000000000000000000000000000000000..54ea7dcf6d678fd47e45ab86ab5a4a00c2c65eb3
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/resource-types.xml
@@ -0,0 +1,6 @@
+
+
+ yarn.resource-types
+ yarn.io/gpu
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-env.sh b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-env.sh
new file mode 100755
index 0000000000000000000000000000000000000000..41c27e15110af913dc2cba9354a335731d5e3a07
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-env.sh
@@ -0,0 +1,127 @@
+# 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.
+
+
+###mod
+export YARN_ROOT_LOGGER=INFO,DRFA
+#export YARN_ROOT_LOGGER=DEBUG,DRFA
+export YARN_LOG_DIR=$HADOOP_LOG_DIR
+export YARN_PID_DIR=$HADOOP_PID_DIR
+
+GC_LOG_DATE=`date +%F`
+GC_LOG_DIR="GC_LOG_DIR_REPLACE"
+#export RESOURCEMANAGER_JVM_OPTS="-Dcom.netease.appname=ResourceManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/resourcemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx20480m -Xms20480m -Xmn5120m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+export RESOURCEMANAGER_JVM_OPTS="-Dcom.netease.appname=ResourceManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/resourcemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6001"
+export NODEMANAGER_JVM_OPTS="-Dcom.netease.appname=NodeManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/nodemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=512M -server -Xmx5120m -Xms5120m -Xmn1024m -XX:SurvivorRatio=4 -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
+#export NODEMANAGER_JVM_OPTS="-Dcom.netease.appname=NodeManager -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/nodemanager.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=6001"
+###mod
+#export YARN_TIMELINESERVER_OPTS="-Dcom.netease.appname=TimelineServer -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/timelineserver.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6001"
+#export YARN_TIMELINEREADER_OPTS="-Dcom.netease.appname=TimelineReaderServer -Djava.net.preferIPv4Stack=true -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$GC_LOG_DIR/timelineserver.gc.log.$GC_LOG_DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=6001"
+
+# User for YARN daemons
+export HADOOP_YARN_USER=${HADOOP_YARN_USER:-yarn}
+
+# resolve links - $0 may be a softlink
+export YARN_CONF_DIR="${YARN_CONF_DIR:-$HADOOP_YARN_HOME/etc/hadoop}"
+
+# some Java parameters
+# export JAVA_HOME=/home/y/libexec/jdk1.6.0/
+if [ "$JAVA_HOME" != "" ]; then
+ #echo "run java in $JAVA_HOME"
+ JAVA_HOME=$JAVA_HOME
+fi
+
+if [ "$JAVA_HOME" = "" ]; then
+ echo "Error: JAVA_HOME is not set."
+ exit 1
+fi
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_HEAP_MAX=-Xmx1000m
+
+# For setting YARN specific HEAP sizes please use this
+# Parameter and set appropriately
+# YARN_HEAPSIZE=1000
+
+# check envvars which might override default args
+if [ "$YARN_HEAPSIZE" != "" ]; then
+ JAVA_HEAP_MAX="-Xmx""$YARN_HEAPSIZE""m"
+fi
+
+# Resource Manager specific parameters
+
+# Specify the max Heapsize for the ResourceManager using a numerical value
+# in the scale of MB. For example, to specify an jvm option of -Xmx1000m, set
+# the value to 1000.
+# This value will be overridden by an Xmx setting specified in either YARN_OPTS
+# and/or YARN_RESOURCEMANAGER_OPTS.
+# If not specified, the default value will be picked from either YARN_HEAPMAX
+# or JAVA_HEAP_MAX with YARN_HEAPMAX as the preferred option of the two.
+#export YARN_RESOURCEMANAGER_HEAPSIZE=1000
+
+# Specify the JVM options to be used when starting the ResourceManager.
+# These options will be appended to the options specified as YARN_OPTS
+# and therefore may override any similar flags set in YARN_OPTS
+export YARN_RESOURCEMANAGER_OPTS="$RESOURCEMANAGER_JVM_OPTS"
+
+# Node Manager specific parameters
+
+# Specify the max Heapsize for the NodeManager using a numerical value
+# in the scale of MB. For example, to specify an jvm option of -Xmx1000m, set
+# the value to 1000.
+# This value will be overridden by an Xmx setting specified in either YARN_OPTS
+# and/or YARN_NODEMANAGER_OPTS.
+# If not specified, the default value will be picked from either YARN_HEAPMAX
+# or JAVA_HEAP_MAX with YARN_HEAPMAX as the preferred option of the two.
+#export YARN_NODEMANAGER_HEAPSIZE=1000
+
+# Specify the JVM options to be used when starting the NodeManager.
+# These options will be appended to the options specified as YARN_OPTS
+# and therefore may override any similar flags set in YARN_OPTS
+export YARN_NODEMANAGER_OPTS="$NODEMANAGER_JVM_OPTS"
+
+# so that filenames w/ spaces are handled correctly in loops below
+IFS=
+
+
+# default log directory & file
+if [ "$YARN_LOG_DIR" = "" ]; then
+ YARN_LOG_DIR="$HADOOP_YARN_HOME/logs"
+fi
+if [ "$YARN_LOGFILE" = "" ]; then
+ YARN_LOGFILE='yarn.log'
+fi
+
+# default policy file for service-level authorization
+if [ "$YARN_POLICYFILE" = "" ]; then
+ YARN_POLICYFILE="hadoop-policy.xml"
+fi
+
+# restore ordinary behaviour
+unset IFS
+
+
+YARN_OPTS="$YARN_OPTS -Dhadoop.log.dir=$YARN_LOG_DIR"
+YARN_OPTS="$YARN_OPTS -Dyarn.log.dir=$YARN_LOG_DIR"
+YARN_OPTS="$YARN_OPTS -Dhadoop.log.file=$YARN_LOGFILE"
+YARN_OPTS="$YARN_OPTS -Dyarn.log.file=$YARN_LOGFILE"
+YARN_OPTS="$YARN_OPTS -Dyarn.home.dir=$YARN_COMMON_HOME"
+YARN_OPTS="$YARN_OPTS -Dyarn.id.str=$YARN_IDENT_STRING"
+YARN_OPTS="$YARN_OPTS -Dhadoop.root.logger=${YARN_ROOT_LOGGER:-INFO,console}"
+YARN_OPTS="$YARN_OPTS -Dyarn.root.logger=${YARN_ROOT_LOGGER:-INFO,console}"
+if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
+ YARN_OPTS="$YARN_OPTS -Djava.library.path=$JAVA_LIBRARY_PATH"
+fi
+YARN_OPTS="$YARN_OPTS -Dyarn.policy.file=$YARN_POLICYFILE"
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-site.xml b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-site.xml
new file mode 100755
index 0000000000000000000000000000000000000000..fd5c84075b13ee2251ed6363675a54931463e101
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/etc_secure/hadoop/yarn-site.xml
@@ -0,0 +1,652 @@
+
+
+
+
+
+
+ local.hostname.rm1
+ YARN_RESOURCE_MANAGER_HOSTS1_REPLACE
+
+
+ local.hostname.rm2
+ YARN_RESOURCE_MANAGER_HOSTS2_REPLACE
+
+
+ local.cluster-id
+ LOCAL_CLUSTER_ID_REPLACE
+
+
+
+
+ yarn.resourcemanager.zk-address
+ YARN_ZK_ADDRESS_REPLACE
+
+
+ yarn.resourcemanager.recovery.enabled
+ true
+
+
+ yarn.resourcemanager.store.class
+ org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
+
+
+ yarn.resourcemanager.zk-timeout-ms
+ 90000
+
+
+ yarn.resourcemanager.am.max-attempts
+ 3
+
+
+ yarn.resourcemanager.state-store.max-completed-applications
+ 200
+
+
+
+
+ yarn.resourcemanager.ha.enabled
+ true
+
+
+ yarn.resourcemanager.cluster-id
+ ${local.cluster-id}
+
+
+ yarn.resourcemanager.ha.rm-ids
+ rm1,rm2
+
+
+
+ yarn.resourcemanager.hostname.rm1
+ ${local.hostname.rm1}
+
+
+
+ yarn.resourcemanager.hostname.rm2
+ ${local.hostname.rm2}
+
+
+
+ yarn.resourcemanager.webapp.address.rm1
+ ${local.hostname.rm1}:8088
+
+
+
+ yarn.resourcemanager.webapp.address.rm2
+ ${local.hostname.rm2}:8088
+
+
+
+
+ yarn.nodemanager.aux-services
+ mapreduce_shuffle,spark_shuffle,timeline_collector
+
+
+ yarn.nodemanager.aux-services.mapreduce_shuffle.class
+ org.apache.hadoop.mapred.ShuffleHandler
+
+
+ yarn.nodemanager.aux-services.spark_shuffle.class
+ org.apache.spark.network.yarn.YarnShuffleService
+
+
+ spark.yarn.shuffle.stopOnFailure
+ true
+
+
+ yarn.nodemanager.aux-services.timeline_collector.class
+ org.apache.hadoop.yarn.server.timelineservice.collector.PerNodeTimelineCollectorsAuxService
+
+
+
+
+ yarn.nodemanager.local-dirs
+ YARN_NODEMANAGER_LOCAL_DIRS_REPLACE
+
+
+ yarn.nodemanager.log-dirs
+ YARN_NODEMANAGER_LOG_DIRS_REPLACE
+
+
+
+
+ Where to aggregate logs in hdfs
+ yarn.nodemanager.remote-app-log-dir
+ YARN_AGGREGATED_LOG_DIR_REPLACE
+
+
+ yarn.log-aggregation-enable
+ true
+
+
+ yarn.log-aggregation.retain-seconds
+ 604800
+
+
+ yarn.log-aggregation.retain-check-interval-seconds
+ 86400
+
+
+ yarn.nodemanager.log-aggregation.compression-type
+ gz
+
+
+
+
+ yarn.resourcemanager.keytab
+ YARN_KEYTAB_LOCATION_REPLACE
+
+
+ yarn.resourcemanager.principal
+ yarn/_HOST@${local.realm}
+
+
+
+
+ yarn.nodemanager.keytab
+ YARN_KEYTAB_LOCATION_REPLACE
+
+
+ yarn.nodemanager.principal
+ yarn/_HOST@${local.realm}
+
+
+
+
+ yarn.nodemanager.container-executor.class
+ org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor
+
+
+ yarn.nodemanager.linux-container-executor.path
+ /etc/yarn/sbin/Linux-amd64-64/container-executor
+
+
+ yarn.nodemanager.linux-container-executor.group
+ yarn
+
+
+
+
+ Minimum request grant-able by the RM scheduler
+ yarn.scheduler.minimum-allocation-mb
+ 512
+
+
+ Maximum request grant-able by the RM scheduler
+ yarn.scheduler.maximum-allocation-mb
+ 32768
+
+
+ yarn.scheduler.minimum-allocation-vcores
+ 1
+
+
+ yarn.scheduler.maximum-allocation-vcores
+ 30
+
+
+ yarn.resourcemanager.scheduler.class
+
+ org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
+
+
+
+ yarn.scheduler.increment-allocation-mb
+ 512
+
+
+ yarn.scheduler.fair.allow-undeclared-pools
+ false
+
+
+
+ yarn.client.nodemanager-connect.max-wait-ms
+ 60000
+
+
+
+
+ yarn.resourcemanager.client.thread-count
+ 64
+
+
+ yarn.resourcemanager.resource-tracker.client.thread-count
+ 64
+
+
+ yarn.resourcemanager.scheduler.client.thread-count
+ 64
+
+
+ yarn.nodemanager.container-manager.thread-count
+ 32
+
+
+ yarn.nodemanager.container-metrics.enable
+ true
+ Todo hbase metrics cleanup mechanism
+
+
+
+
+ The minimum space that must be available on a disk for
+ it to be used. This applies to yarn.nodemanager.local-dirs and
+ yarn.nodemanager.log-dirs.
+ yarn.nodemanager.disk-health-checker.min-free-space-per-disk-mb
+ 1000
+
+
+ Defines how often NMs wake up to upload log files.
+ The default value is -1. By default, the logs will be uploaded when
+ the application is finished. By setting this configure, logs can be uploaded
+ periodically when the application is running. The minimum rolling-interval-seconds
+ can be set is 3600.
+
+ yarn.nodemanager.log-aggregation.roll-monitoring-interval-seconds
+ 3600
+
+
+ Enable the node manager to recover after starting
+ yarn.nodemanager.recovery.enabled
+ true
+
+
+ The local filesystem directory in which the node manager will
+ store state when recovery is enabled.
+ yarn.nodemanager.recovery.dir
+ YARN_NODEMANAGER_RECOVERY_DIR_REPLACE
+
+
+
+
+ yarn.nodemanager.resource.memory-mb
+ 204800
+
+
+ yarn.nodemanager.resource.cpu-vcores
+ 40
+
+
+
+ yarn.admin.acl
+ hadoop,yarn
+
+
+ yarn.acl.enable
+ true
+
+
+
+
+ yarn.resourcemanager.nodes.exclude-path
+ YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH_REPLACE
+
+
+ If true, ResourceManager will have proxy-user privileges.
+ Use case: In a secure cluster, YARN requires the user hdfs delegation-tokens to
+ do localization and log-aggregation on behalf of the user. If this is set to true,
+ ResourceManager is able to request new hdfs delegation tokens on behalf of
+ the user. This is needed by long-running-service, because the hdfs tokens
+ will eventually expire and YARN requires new valid tokens to do localization
+ and log-aggregation. Note that to enable this use case, the corresponding
+ HDFS NameNode has to configure ResourceManager as the proxy-user so that
+ ResourceManager can itself ask for new tokens on behalf of the user when
+ tokens are past their max-life-time.
+ yarn.resourcemanager.proxy-user-privileges.enabled
+ true
+
+
+
+
+ yarn.resourcemanager.webapp.delegation-token-auth-filter.enabled
+ false
+
+
+
+ hadoop.http.filter.initializers
+ org.apache.hadoop.security.AuthenticationFilterInitializer
+
+
+ hadoop.http.authentication.type
+
+ kerberos
+
+
+
+ yarn.nodemanager.container.use.serialgc.enable
+ true
+
+
+
+
+ Indicate to clients whether Timeline service is enabled or not.
+ If enabled, the TimelineClient library used by end-users will post entities
+ and events to the Timeline server.
+ yarn.timeline-service.enabled
+ true
+
+
+
+ The setting that controls whether yarn system metrics is
+ published on the timeline server or not by RM.
+ yarn.resourcemanager.system-metrics-publisher.enabled
+ true
+
+
+
+ Indicate to clients whether to query generic application
+ data from timeline history-service or not. If not enabled then application
+ data is queried only from Resource Manager.
+ yarn.timeline-service.generic-application-history.enabled
+ true
+
+
+
+ yarn.timeline-service.http-authentication.type
+
+ kerberos
+
+
+
+ yarn.timeline-service.principal
+ yarn/_HOST@${local.realm}
+
+
+
+ yarn.timeline-service.keytab
+ YARN_KEYTAB_LOCATION_REPLACE
+
+
+
+ yarn.timeline-service.http-authentication.kerberos.principal
+ HTTP/_HOST@${local.realm}
+
+
+
+ yarn.timeline-service.http-authentication.kerberos.keytab
+ HTTP_KEYTAB_LOCATION_REPLACE
+
+
+
+ yarn.timeline-service.hostname
+ YARN_TIMELINE_HOST_REPLACE
+
+
+
+ yarn.timeline-service.hbase.coprocessor.jar.hdfs.location
+ /hbase/coprocessor
+
+
+
+ URL for log aggregation server web service
+ yarn.log.server.web-service.url
+ http://YARN_TIMELINE_HOST_REPLACE:8189/ws/v2/applicationlog
+
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.path
+ YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE
+
+
+
+ yarn.timeline-service.leveldb-state-store.path
+ YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.read-cache-size
+ 104857600
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.start-time-read-cache-size
+ 10000
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.start-time-write-cache-size
+ 10000
+
+
+
+ yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms
+ 300000
+
+
+
+ yarn.timeline-service.recovery.enabled
+ true
+
+
+
+ yarn.timeline-service.state-store-class
+ org.apache.hadoop.yarn.server.timeline.recovery.LeveldbTimelineStateStore
+
+
+
+ yarn.timeline-service.store-class
+ org.apache.hadoop.yarn.server.timeline.EntityGroupFSTimelineStore
+
+
+
+ yarn.timeline-service.ttl-enable
+ true
+
+
+
+ yarn.timeline-service.ttl-ms
+ 2678400000
+
+
+
+
+ yarn.timeline-service.version
+ 2.0f
+
+
+
+ The setting that controls whether yarn system metrics is
+ published on the Timeline service or not by RM And NM.
+ yarn.system-metrics-publisher.enabled
+ true
+
+
+
+ The setting that controls whether yarn container events are
+ published to the timeline service or not by RM. This configuration setting
+ is for ATS V2.
+
+ yarn.rm.system-metrics-publisher.emit-container-events
+ true
+
+
+
+ Optional URL to an hbase-site.xml configuration file to be
+ used to connect to the timeline-service hbase cluster. If empty or not
+ specified, then the HBase configuration will be loaded from the classpath.
+ When specified the values in the specified configuration file will override
+ those from the ones that are present on the classpath.
+
+ yarn.timeline-service.hbase.configuration.file
+ YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE_REPLACE
+
+
+
+
+ yarn.timeline-service.versions
+ 1.5f,2.0f
+
+
+
+ yarn.timeline-service.entity-group-fs-store.active-dir
+ YARN_TIMELINE_FS_STORE_DIR_REPLACE/active
+
+
+
+ yarn.timeline-service.entity-group-fs-store.done-dir
+ YARN_TIMELINE_FS_STORE_DIR_REPLACE/done
+
+
+
+
+ yarn.timeline-service.reader.webapp.address
+ YARN_TIMELINE_HOST_REPLACE:8189
+
+
+
+ yarn.timeline-service.entity-group-fs-store.summary-store
+ org.apache.hadoop.yarn.server.timeline.RollingLevelDBTimelineStore
+
+
+
+ Enable services rest api on ResourceManager.
+ yarn.webapp.api-service.enable
+ true
+
+
+
+ The domain name for Hadoop cluster associated records. As short as possible.
+ hadoop.registry.dns.domain-name
+ ml
+
+
+
+ The DNS functionality is enabled for the cluster. Default is false.
+ hadoop.registry.dns.enabled
+ true
+
+
+ Address associated with the network interface to which the DNS listener should bind.
+ hadoop.registry.dns.bind-address
+ YARN_REGISTRY_DNS_HOST_REPLACE
+
+
+ The port number for the DNS listener. The default port is 5353.
+ If the standard privileged port 53 is used, make sure start the DNS with jsvc support.
+ hadoop.registry.dns.bind-port
+
+ YARN_REGISTRY_DNS_HOST_PORT_REPLACE
+
+
+
+
+ The Kerberos keytab file to be used for spnego filter for the NM web interface.
+
+ yarn.nodemanager.webapp.spnego-keytab-file
+ HTTP_KEYTAB_LOCATION_REPLACE
+
+
+
+
+ The Kerberos principal to be used for spnego filter for the NM web interface.
+
+ yarn.nodemanager.webapp.spnego-principal
+ HTTP/_HOST@${local.realm}
+
+
+
+
+ The Kerberos keytab file to be used for spnego filter for the RM web interface.
+
+ yarn.resourcemanager.webapp.spnego-keytab-file
+ HTTP_KEYTAB_LOCATION_REPLACE
+
+
+
+
+ The Kerberos principal to be used for spnego filter for the RM web interface.
+
+ yarn.resourcemanager.webapp.spnego-principal
+ HTTP/_HOST@${local.realm}
+
+
+
+
+ yarn.nodemanager.linux-container-executor.resources-handler.class
+ org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler
+
+
+ yarn.nodemanager.linux-container-executor.cgroups.mount
+ false
+
+
+ yarn.nodemanager.resource.percentage-physical-cpu-limit
+ 80
+
+
+ Whether virtual memory limits will be enforced for containers.
+ yarn.nodemanager.vmem-check-enabled
+ false
+
+
+
+ Whether YARN CGroups memory tracking is enabled.
+ yarn.nodemanager.resource.memory.enabled
+ true
+
+
+
+
+ yarn.nodemanager.runtime.linux.docker.default-container-network
+ YARN_DOCKER_CONTAINER_DEFAULT_NETWORK_REPLACE
+
+
+ yarn.nodemanager.runtime.linux.allowed-runtimes
+ default,docker
+
+
+ yarn.nodemanager.runtime.linux.docker.allowed-container-networks
+ YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS_REPLACE
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.allowed
+ false
+
+
+ yarn.nodemanager.runtime.linux.docker.privileged-containers.acl
+
+
+
+ yarn.nodemanager.runtime.linux.docker.capabilities
+ CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE
+
+
+
+
+ yarn.webapp.ui2.enable
+ true
+
+
+
+
+
+ yarn.service.base.path
+ /tmp/.LOCAL_CLUSTER_ID_REPLACE/
+
+
+
+ yarn.nodemanager.address
+ 0.0.0.0:45454
+
+
+
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-historyserver.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-historyserver.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ed84feaa8f67835640a71e7ee2d79291658faf81
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-historyserver.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "mapred" ];then
+ echo "[ERROR]:jobhistory must be started with the [mapred] user!"
+fi
+
+YARN_LOGFILE=mr-historyserver.log ${common_bin}/mr-jobhistory-daemon.sh start historyserver
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-mr-jobhistory.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-mr-jobhistory.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5d54144472a7d10d19ac09718a94577f5c7b61b7
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-mr-jobhistory.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+YARN_LOGFILE=mr-jobhistory.log ${common_bin}/mr-jobhistory-daemon.sh start historyserver
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-nodemanager.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-nodemanager.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5c5cac2824e87ff76b764773f5a3ebea3aa60248
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-nodemanager.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:nodemanager must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=nodemanager.log ${common_bin}/yarn-daemon.sh start nodemanager
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-registrydns.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-registrydns.sh
new file mode 100644
index 0000000000000000000000000000000000000000..8d2aa7c8895dbb41758401ee6f5e1f51a8c84ba5
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-registrydns.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "root" ];then
+ echo "[ERROR]:Registrydns must be started with the [root] user!"
+fi
+
+JSVC_HOME=${common_bin}/../bin YARN_LOGFILE=registrydns.log ${common_bin}/yarn-daemon.sh start registrydns
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-resourcemanager.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-resourcemanager.sh
new file mode 100644
index 0000000000000000000000000000000000000000..217b2bf0e40624cc2401a671d3736f9a851c45f8
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-resourcemanager.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:resourcemanager must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=resourcemanager.log ${common_bin}/yarn-daemon.sh start resourcemanager
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelinereader.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelinereader.sh
new file mode 100644
index 0000000000000000000000000000000000000000..33e1586089780a69f48e96ef206ad352f1837a41
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelinereader.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:timelinereader must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=timelinereader.log ${common_bin}/yarn-daemon.sh start timelinereader
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelineserver.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelineserver.sh
new file mode 100644
index 0000000000000000000000000000000000000000..fbe45be24f4cc41c88cac71cb69991a0a27c9276
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/start-timelineserver.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:timelineserver must be started with the [yarn] user!"
+fi
+
+HADOOP_SHELL_SCRIPT_DEBUG=true YARN_LOGFILE=timelineserver.log ${common_bin}/yarn-daemon.sh start timelineserver
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-historyserver.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-historyserver.sh
new file mode 100755
index 0000000000000000000000000000000000000000..133ff5d2ea56c9ba127b727bb95a4faa6638e012
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-historyserver.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "mapred" ];then
+ echo "[ERROR]:jobhistory must be started with the [mapred] user!"
+fi
+
+YARN_LOGFILE=mr-historyserver.log ${common_bin}/mr-jobhistory-daemon.sh stop historyserver
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-mr-jobhistory.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-mr-jobhistory.sh
new file mode 100755
index 0000000000000000000000000000000000000000..98b9ae0435dd5feca29c4b25e3bb5d0bfeb755d7
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-mr-jobhistory.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+YARN_LOGFILE=mr-jobhistory.log ${common_bin}/mr-jobhistory-daemon.sh stop historyserver
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-nodemanager.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-nodemanager.sh
new file mode 100755
index 0000000000000000000000000000000000000000..64261ccf2b0c8273fe67629e08079ab6d3182e27
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-nodemanager.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:nodemanager must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=nodemanager.log ${common_bin}/yarn-daemon.sh stop nodemanager
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-registrydns.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-registrydns.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a6f81c1eb64017e0e553c50137a4b383da5ccdf7
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-registrydns.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "root" ];then
+ echo "[ERROR]:Registrydns must be started with the [root] user!"
+fi
+
+JSVC_HOME=${common_bin}/../bin YARN_LOGFILE=registrydns.log ${common_bin}/yarn-daemon.sh stop registrydns
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-resourcemanager.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-resourcemanager.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9f1b8cfe617c8add03fa98e5cd1a0cd139f596c9
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-resourcemanager.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:resourcemanager must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=resourcemanager.log ${common_bin}/yarn-daemon.sh stop resourcemanager
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelinereader.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelinereader.sh
new file mode 100755
index 0000000000000000000000000000000000000000..17eb8d9709ae9d4a4bd32cf3f61d1ccabc82f060
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelinereader.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:timelinereader must be started with the [yarn] user!"
+fi
+
+YARN_LOGFILE=timelinereader.log ${common_bin}/yarn-daemon.sh stop timelinereader
diff --git a/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelineserver.sh b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelineserver.sh
new file mode 100755
index 0000000000000000000000000000000000000000..071ee77ad13eea62bcb5e2693029cd83533c4864
--- /dev/null
+++ b/dev-support/submarine-installer/package/hadoop/yarn/sbin/stop-timelineserver.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# 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.
+
+cd `dirname $0`
+common_bin=`pwd`
+
+if [ `whoami` != "yarn" ];then
+ echo "[ERROR]:timelineserver must be started with the [yarn] user!"
+fi
+
+HADOOP_SHELL_SCRIPT_DEBUG=true YARN_LOGFILE=timelineserver.log ${common_bin}/yarn-daemon.sh stop timelineserver
diff --git a/dev-support/submarine-installer/package/submarine/submarine.sh b/dev-support/submarine-installer/package/submarine/submarine.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b5c4b039760d97f27671b0cdcec54be1c467af4e
--- /dev/null
+++ b/dev-support/submarine-installer/package/submarine/submarine.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+# 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.
+
+# Solution: Grant user yarn the access to /sys/fs/cgroup/cpu,cpuacct,
+# which is the subfolder of cgroup mount destination.
+chown :yarn -R /sys/fs/cgroup/cpu,cpuacct
+chmod g+rwx -R /sys/fs/cgroup/cpu,cpuacct
+
+# Grant user yarn the access to /sys/fs/cgroup/memory,
+# which is the subfolder of cgroup mount destination.
+chown :yarn -R /sys/fs/cgroup/memory
+chmod g+rwx -R /sys/fs/cgroup/memory
+
+
+# If GPUs are used,the access to cgroup devices folder is needed as well
+chown :yarn -R /sys/fs/cgroup/devices
+chmod g+rwx -R /sys/fs/cgroup/devices
diff --git a/dev-support/submarine-installer/scripts/calico.sh b/dev-support/submarine-installer/scripts/calico.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b3eb80be1b5ee6c9da09ff8ab1feefdc89d68fcc
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/calico.sh
@@ -0,0 +1,228 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description download calico bin
+## @audience public
+## @stability stable
+function download_calico_bin()
+{
+ # submarine http server
+ if [[ -n "$DOWNLOAD_HTTP" ]]; then
+ MY_CALICOCTL_DOWNLOAD_URL=${DOWNLOAD_HTTP}/downloads/calico/calicoctl
+ MY_CALICO_DOWNLOAD_URL=${DOWNLOAD_HTTP}/downloads/calico/calico
+ MY_CALICO_IPAM_DOWNLOAD_URL=${DOWNLOAD_HTTP}/downloads/calico/calico-ipam
+ else
+ MY_CALICOCTL_DOWNLOAD_URL=${CALICOCTL_DOWNLOAD_URL}
+ MY_CALICO_DOWNLOAD_URL=${CALICO_DOWNLOAD_URL}
+ MY_CALICO_IPAM_DOWNLOAD_URL=${CALICO_IPAM_DOWNLOAD_URL}
+ fi
+
+ mkdir -p "${DOWNLOAD_DIR}/calico"
+
+ if [[ -f ${DOWNLOAD_DIR}/calico/calico ]]; then
+ echo "${DOWNLOAD_DIR}/calico/calico already exists."
+ else
+ echo "download ${MY_CALICO_DOWNLOAD_URL} ..."
+ wget -P "${DOWNLOAD_DIR}/calico" "${MY_CALICO_DOWNLOAD_URL}"
+ fi
+
+ if [[ -f ${DOWNLOAD_DIR}/calico/calicoctl ]]; then
+ echo "${DOWNLOAD_DIR}/calico already exists."
+ else
+ echo "download ${MY_CALICOCTL_DOWNLOAD_URL} ..."
+ wget -P "${DOWNLOAD_DIR}/calico" "${MY_CALICOCTL_DOWNLOAD_URL}"
+ fi
+
+ if [[ -f ${DOWNLOAD_DIR}/calico/calico-ipam ]]; then
+ echo "${DOWNLOAD_DIR}/calico/calico-ipam already exists."
+ else
+ echo "download ${MY_CALICO_IPAM_DOWNLOAD_URL} ..."
+ wget -P "${DOWNLOAD_DIR}/calico" "${MY_CALICO_IPAM_DOWNLOAD_URL}"
+ fi
+}
+
+## @description install calico bin
+## @audience public
+## @stability stable
+function install_calico_bin()
+{
+ download_calico_bin
+
+ sudo cp -f "${DOWNLOAD_DIR}/calico/calico" /usr/bin/calico
+ sudo cp -f "${DOWNLOAD_DIR}/calico/calicoctl" /usr/bin/calicoctl
+ sudo cp -f "${DOWNLOAD_DIR}/calico/calico-ipam" /usr/bin/calico-ipam
+
+ sudo chmod +x /usr/bin/calico
+ sudo chmod +x /usr/bin/calicoctl
+ sudo chmod +x /usr/bin/calico-ipam
+}
+
+## @description install calico config
+## @audience public
+## @stability stable
+function install_calico_config()
+{
+ sudo mkdir -p /etc/calico
+
+ cp -rf "${PACKAGE_DIR}/calico" "${INSTALL_TEMP_DIR}/"
+
+ # 1. replace etcdEndpoints
+ # etcdEndpoints: https://10.196.69.173:2379,https://10.196.69.174:2379,https://10.196.69.175:2379
+ etcdEndpoints=''
+ index=0
+ etcdHostsSize=${#ETCD_HOSTS[@]}
+ for item in "${ETCD_HOSTS[@]}"
+ do
+ index=$((index+1))
+ etcdEndpoints="${etcdEndpoints}http:\\/\\/${item}:2379"
+ if [[ ${index} -lt ${etcdHostsSize} ]]; then
+ etcdEndpoints=${etcdEndpoints}","
+ fi
+ done
+ # echo "etcdEndpoints=${etcdEndpoints}"
+ sed -i "s/ETCD_ENDPOINTS_REPLACE/${etcdEndpoints}/g" "$INSTALL_TEMP_DIR/calico/calicoctl.cfg"
+
+ if [[ ! -d /etc/calico ]]; then
+ sudo mkdir /etc/calico
+ else
+ sudo rm -rf /etc/calico/*
+ fi
+
+ sudo cp -f "$INSTALL_TEMP_DIR/calico/calicoctl.cfg" /etc/calico/calicoctl.cfg
+
+ sed -i "s/ETCD_ENDPOINTS_REPLACE/${etcdEndpoints}/g" "$INSTALL_TEMP_DIR/calico/calico-node.service"
+ sed -i "s/CALICO_IPV4POOL_CIDR_REPLACE/${CALICO_IPV4POOL_CIDR}/g" "$INSTALL_TEMP_DIR/calico/calico-node.service"
+ sudo cp "$INSTALL_TEMP_DIR/calico/calico-node.service" /etc/systemd/system/
+
+ sudo systemctl daemon-reload
+ sudo systemctl enable calico-node.service
+}
+
+## @description modify kernel network config
+## @audience public
+## @stability stable
+function kernel_network_config()
+{
+ if [ "$(grep -c "net.ipv4.conf.all.rp_filter=1" /etc/sysctl.conf)" -eq '0' ]; then
+ sudo echo "net.ipv4.conf.all.rp_filter=1" >>/etc/sysctl.conf
+ fi
+
+ if [ "$(grep -c "net.ipv4.ip_forward=1" /etc/sysctl.conf)" -eq '0' ]; then
+ sudo echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
+ fi
+
+ sudo sysctl -p
+}
+
+## @description check if the calico-network exist
+## @audience public
+## @stability stable
+function calico_network_exist()
+{
+ local dockerNetworkInfo
+ dockerNetworkInfo=$(docker network ls --filter NAME="${CALICO_NETWORK_NAME}")
+ echo "${dockerNetworkInfo}" | grep "${CALICO_NETWORK_NAME}"
+}
+
+## @description verification calico
+## @audience public
+## @stability stable
+function verification_calico()
+{
+ echo " ===== Check if the network between 2 containers can be connected ====="
+ local calicoNetworkExist
+ calicoNetworkExist=$(calico_network_exist)
+ if [[ "$calicoNetworkExist" = "" ]]; then
+ echo "Create a calico network"
+ docker network create --driver calico --ipam-driver calico-ipam "${CALICO_NETWORK_NAME}"
+ else
+ echo "calico network ${CALICO_NETWORK_NAME} already exists."
+ fi
+
+ local verifyA="verify-calico-network-A"
+ local verifyAInfo
+ verifyAInfo=$(containers_exist ${verifyA})
+ if [[ -n "$verifyAInfo" ]]; then
+ echo "Delete existing container ${verifyA}."
+ docker stop ${verifyA}
+ docker rm ${verifyA}
+ fi
+ echo "Create containers verify-calico-network-A"
+ docker run --net "${CALICO_NETWORK_NAME}" --name ${verifyA} -tid busybox
+
+ local verifyB="verify-calico-network-B"
+ local verifyBInfo
+ verifyBInfo=$(containers_exist ${verifyB})
+ if [[ -n "$verifyBInfo" ]]; then
+ echo "Delete existing container ${verifyB}."
+ docker stop ${verifyB}
+ docker rm ${verifyB}
+ fi
+ echo "Create containers verify-calico-network-B"
+ docker run --net "${CALICO_NETWORK_NAME}" --name ${verifyB} -tid busybox
+
+ echo -e "\\033[33m${verifyA} ping ${verifyB}\\033[0m"
+ docker exec ${verifyA} ping ${verifyB} -c 5
+}
+
+## @description install calico
+## @audience public
+## @stability stable
+function install_calico()
+{
+ kernel_network_config
+ install_calico_bin
+ install_calico_config
+ start_calico
+ verification_calico
+}
+
+## @description uninstall calico
+## @audience public
+## @stability stable
+function uninstall_calico()
+{
+ echo "stop calico-node.service"
+ sudo systemctl stop calico-node.service
+
+ echo "rm /usr/bin/calico ..."
+ sudo rm /usr/bin/calicoctl
+ sudo rm /usr/bin/calico
+ sudo rm /usr/bin/calico-ipam
+
+ sudo rm -rf /etc/calico/
+ sudo rm /etc/systemd/system/calico-node.service
+ systemctl daemon-reload
+}
+
+## @description start calico
+## @audience public
+## @stability stable
+function start_calico()
+{
+ sudo systemctl restart calico-node.service
+ sudo systemctl status calico-node.service
+}
+
+## @description stop calico
+## @audience public
+## @stability stable
+function stop_calico()
+{
+ sudo systemctl stop calico-node.service
+ sudo systemctl status calico-node.service
+}
diff --git a/dev-support/submarine-installer/scripts/combine-docker-daemons.py b/dev-support/submarine-installer/scripts/combine-docker-daemons.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d5ff58d4ec0d9a9774a52b99cb449eb64505265
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/combine-docker-daemons.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+# 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.
+
+import json
+import sys
+
+def combineJsons(jsonFile1, jsonFile2, outputFile):
+ dict1 = json.load(open(jsonFile1))
+ dict2 = json.load(open(jsonFile2))
+ dict3 = dict(dict1.items() + dict2.items())
+
+ with open(outputFile, 'w') as output:
+ json.dump(dict3, output, indent=2, sort_keys=True)
+
+ return True
+
+if __name__ == '__main__':
+ if (len(sys.argv) < 4):
+ raise Exception,u"3 arguments needed"
+
+ print(combineJsons(sys.argv[1], sys.argv[2], sys.argv[3]))
diff --git a/dev-support/submarine-installer/scripts/docker.sh b/dev-support/submarine-installer/scripts/docker.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c282a2a8d38e931f4ba01da72799406cd7553008
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/docker.sh
@@ -0,0 +1,178 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description download docker rmp
+## @audience public
+## @stability stable
+function download_docker_rpm()
+{
+ # download http server
+ if [[ -n "$DOWNLOAD_HTTP" ]]; then
+ MY_DOCKER_ENGINE_RPM="${DOWNLOAD_HTTP}/downloads/docker/${DOCKER_ENGINE_RPM}"
+ else
+ # Trim the last slash of DOCKER_REPO
+ DOCKER_REPO_TRIMED="$(echo -e "${DOCKER_REPO}" | sed -e 's/\/*$//')"
+ MY_DOCKER_ENGINE_RPM=${DOCKER_REPO_TRIMED}/${DOCKER_ENGINE_RPM}
+ fi
+
+ if [[ -f ${DOWNLOAD_DIR}/docker/${DOCKER_ENGINE_RPM} ]]; then
+ echo "${DOWNLOAD_DIR}/docker/${DOCKER_ENGINE_RPM} already exists."
+ else
+ echo "download ${MY_DOCKER_ENGINE_RPM} ..."
+ wget -P "${DOWNLOAD_DIR}/docker/" "${MY_DOCKER_ENGINE_RPM}"
+ if [[ $? -ne 0 ]]; then
+ echo -e "\\033[32mshell:> Failed to download ${DOCKER_ENGINE_RPM} of docker
+ from ${MY_DOCKER_ENGINE_RPM} \\033[0m"
+ fi
+ fi
+}
+
+## @description install docker bin
+## @audience public
+## @stability stable
+function install_docker_bin()
+{
+ download_docker_rpm
+
+ sudo yum -y localinstall "${DOWNLOAD_DIR}/docker/${DOCKER_ENGINE_RPM}"
+}
+
+## @description uninstall docker bin
+## @audience public
+## @stability stable
+function uninstall_docker_bin()
+{
+ sudo yum -y remove "${DOCKER_VERSION}"
+}
+
+## @description install docker config
+## @audience public
+## @stability stable
+function install_docker_config()
+{
+ rm -rf "${INSTALL_TEMP_DIR}/docker"
+ cp -rf "${PACKAGE_DIR}/docker" "${INSTALL_TEMP_DIR}/"
+
+ # replace cluster-store
+ # "cluster-store":"etcd://10.196.69.173:2379,10.196.69.174:2379,10.196.69.175:2379"
+ # char '/' need to escape '\/'
+ clusterStore="etcd:\\/\\/"
+ index=1
+ etcdHostsSize=${#ETCD_HOSTS[@]}
+ for item in "${ETCD_HOSTS[@]}"
+ do
+ clusterStore="${clusterStore}${item}:2379"
+ if [[ ${index} -lt ${etcdHostsSize} ]]; then
+ clusterStore=${clusterStore}","
+ fi
+ index=$((index+1))
+ done
+ # echo "clusterStore=${clusterStore}"
+ sed -i "s/CLUSTER_STORE_REPLACE/${clusterStore}/g" "$INSTALL_TEMP_DIR/docker/daemon.json"
+
+ sed -i "s/DOCKER_REGISTRY_REPLACE/${DOCKER_REGISTRY}/g" "$INSTALL_TEMP_DIR/docker/daemon.json"
+ sed -i "s/LOCAL_HOST_IP_REPLACE/${LOCAL_HOST_IP}/g" "$INSTALL_TEMP_DIR/docker/daemon.json"
+ YARN_REGISTRY_DNS_IP=$(getent hosts "${YARN_REGISTRY_DNS_HOST}" | awk '{ print $1 }')
+ sed -i "s/YARN_REGISTRY_DNS_HOST_REPLACE/${YARN_REGISTRY_DNS_IP}/g" "$INSTALL_TEMP_DIR/docker/daemon.json"
+
+ hosts=${LOCAL_DNS_HOST//,/ }
+ hosts_length=0
+ for element in $hosts
+ do
+ hosts_length=$((${hosts_length} + 1))
+ if [ ${hosts_length} != 1 ]; then
+ NEW_LOCAL_DNS_HOST="${NEW_LOCAL_DNS_HOST}, "
+ fi
+ NEW_LOCAL_DNS_HOST="${NEW_LOCAL_DNS_HOST}\"${element}\""
+ done
+ sed -i "s/LOCAL_DNS_HOST_REPLACE/${NEW_LOCAL_DNS_HOST}/g" "$INSTALL_TEMP_DIR/docker/daemon.json"
+
+ # Delete the ASF license comment in the daemon.json file, otherwise it will cause a json format error.
+ sed -i '1,16d' "$INSTALL_TEMP_DIR/docker/daemon.json"
+
+ if [ ! -d "/etc/docker" ]; then
+ sudo mkdir /etc/docker
+ fi
+
+ sudo cp "$INSTALL_TEMP_DIR/docker/daemon.json" /etc/docker/
+ sudo cp "$INSTALL_TEMP_DIR/docker/docker.service" /etc/systemd/system/
+
+ # Change docker store path
+ if [[ -n "${DOCKER_STORE_PATH}" ]]; then
+ mkdir -p "${DOCKER_STORE_PATH}"
+ cp -r /var/lib/docker/* "${DOCKER_STORE_PATH}"
+ rm -rf /var/lib/docker
+ ln -s "${DOCKER_STORE_PATH}" "/var/lib/docker"
+ fi
+}
+
+## @description install docker
+## @audience public
+## @stability stable
+function install_docker()
+{
+ install_docker_bin
+ install_docker_config
+
+ sudo systemctl daemon-reload
+ sudo systemctl enable docker.service
+}
+
+## @description uninstall docker
+## @audience public
+## @stability stable
+function uninstall_docker()
+{
+ echo "stop docker service"
+ sudo systemctl stop docker
+
+ echo "remove docker"
+ uninstall_docker_bin
+
+ sudo rm /etc/systemd/system/docker.service
+
+ sudo systemctl daemon-reload
+}
+
+## @description start docker
+## @audience public
+## @stability stable
+function start_docker()
+{
+ sudo systemctl restart docker
+ sudo systemctl status docker
+ docker info
+}
+
+## @description stop docker
+## @audience public
+## @stability stable
+function stop_docker()
+{
+ sudo systemctl stop docker
+ sudo systemctl status docker
+}
+
+## @description check if the containers exist
+## @audience public
+## @stability stable
+function containers_exist()
+{
+ local dockerContainersInfo
+ dockerContainersInfo=$(docker ps -a --filter NAME="$1")
+ echo "${dockerContainersInfo}" | grep "$1"
+}
diff --git a/dev-support/submarine-installer/scripts/download-server.sh b/dev-support/submarine-installer/scripts/download-server.sh
new file mode 100644
index 0000000000000000000000000000000000000000..244d7a880cb8e50067f7ce55cb327f680c2023c5
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/download-server.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description start download server
+## @audience public
+## @stability stable
+function start_download_server()
+{
+ if [[ -n "$DOWNLOAD_SERVER_IP" && "$DOWNLOAD_SERVER_IP" != "$LOCAL_HOST_IP" ]]; then
+ echo -e "\\033[31mERROR: Only $DOWNLOAD_SERVER_IP can start the download service.\\033[0m"
+ return 1
+ fi
+
+ echo -e "You can put the install package file in the \\033[34m${DOWNLOAD_DIR}\\033[0m folder first, Or automatic download."
+ echo -n "Do you want to start download http server?[y|n]"
+ read -r myselect
+ if [[ "$myselect" = "y" || "$myselect" = "Y" ]]
+ then
+ IS_DOWNLOAD_SERVER=true
+ download_etcd_bin
+ download_calico_bin
+ download_docker_rpm
+ download_nvidia_driver
+ download_nvidia_docker_bin
+ download_yarn_container_executor
+
+ python -m SimpleHTTPServer "${DOWNLOAD_SERVER_PORT}"
+ fi
+}
diff --git a/dev-support/submarine-installer/scripts/environment.sh b/dev-support/submarine-installer/scripts/environment.sh
new file mode 100644
index 0000000000000000000000000000000000000000..916695c1313d56c0bc01eabd39e86cbbe2c0ad95
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/environment.sh
@@ -0,0 +1,219 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description check operation System
+## @audience public
+## @stability stable
+function check_operationSystem()
+{
+ echo -e "The submarine assembly support \\033[32m[centos-release-7-5.1804.el7.centos.x86_64]\\033[0m or higher operating system version."
+
+ case ${OPERATING_SYSTEM} in
+ centos)
+ local operationSystemVersion
+ operationSystemVersion=$(rpm --query centos-release)
+ echo -e "The current operating system version is \\e[31m[${operationSystemVersion}]\\e[0m"
+ ;;
+ *)
+ echo -e "\\033[31mWARN: The submarine assembly Unsupported [${OPERATING_SYSTEM}] operating system\\033[0m"
+ ;;
+ esac
+}
+
+## @description update operation System Kernel
+## @audience public
+## @stability stable
+function update_operationSystemKernel()
+{
+ echo "If the server is unable to connect to the network, execute the following command yourself:
+ wget http://vault.centos.org/7.5.1804/os/x86_64/Packages/kernel-headers-3.10.0-862.el7.x86_64.rpm
+ rpm -ivh kernel-headers-3.10.0-862.el7.x86_64.rpm"
+
+ echo -n "Do you want to kernel upgrades?[y|n]"
+ read -r myselect
+ if [[ "$myselect" = "y" || "$myselect" = "Y" ]]
+ then
+ echo "Now try to use the yum command for kernel upgrades ..."
+ yum install "kernel-devel-$(uname -r)" "kernel-headers-$(uname -r)"
+
+ local kernelVersion
+ kernelVersion=$(uname -r)
+ echo -e "After the upgrade, the operating system kernel version is \\e[31m${kernelVersion}\\e[0m"
+ fi
+}
+
+## @description check operation system kernel
+## @audience public
+## @stability stable
+function check_operationSystemKernel()
+{
+case ${OPERATING_SYSTEM} in
+centos)
+ local kernelVersion
+ kernelVersion=$(uname -r)
+
+ echo -e "Submarine support operating system kernel version is \\033[32m 3.10.0-862.el7.x86_64 \\033[0m"
+ echo -e "Current operating system kernel version is \\e[31m${kernelVersion}\\e[0m"
+
+ update_operationSystemKernel
+ ;;
+*)
+ echo -e "\\033[31m WARN: The submarine assembly Unsupported operating system [${OPERATING_SYSTEM}] \\033[0m"
+ ;;
+esac
+}
+
+## @description get gcc version
+## @audience public
+## @stability stable
+function get_gcc_version()
+{
+ local gccVersion
+ gccVersion=$(gcc --version)
+ version=${gccVersion%Copyright*}
+ echo "$version"
+}
+
+## @description install gcc
+## @audience public
+## @stability stable
+function install_gcc()
+{
+ echo -n "Do you want to install gcc?[y|n]"
+ read -r myselect
+ if [[ "$myselect" = "y" || "$myselect" = "Y" ]]; then
+ echo "Execute the yum install gcc make g++ command"
+ yum install gcc make g++
+
+ local gccVersion
+ gccVersion=$(gcc --version)
+ echo -e "After the install, the gcc version is \\e[31m${gccVersion}\\e[0m"
+ fi
+}
+
+## @description check gcc Version
+## @audience public
+## @stability stable
+function check_gccVersion()
+{
+ local gccVersionInfo
+ gccVersionInfo=$(gcc --version)
+ local gccVersion=${gccVersionInfo%Copyright*}
+
+ if [[ "$gccVersion" = "" ]]; then
+ echo "The gcc was not installed on the system. Automated installation ..."
+ install_gcc
+ else
+ echo -e "Submarine gcc version need \\033[34mgcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)\\033[0m or higher."
+ echo -e "Current gcc version was \\033[34m${gccVersion}\\033[0m"
+ fi
+}
+
+## @description check GPU
+## @audience public
+## @stability stable
+function check_GPU()
+{
+ gpuInfo=$(lspci | grep -i nvidia)
+
+ if [[ "$gpuInfo" = "" ]]; then
+ echo -e "\\033[31mERROR: The system did not detect the GPU graphics card.\\033[0m"
+ else
+ echo -e "\\033[32mINFO: The system detect the GPU graphics card.\\033[0m"
+ fi
+}
+
+## @description check user group
+## @audience public
+## @stability stable
+function check_userGroup()
+{
+ echo -e "check hadoop user group ..."
+
+ echo -e "Hadoop runs the required user [hdfs, mapred, yarn] and groups [hdfs, mapred, yarn, hadoop] installed by ambari."
+ echo -e "If you are not using ambari for hadoop installation,
+then you can add the user and group by root by executing the following command:
+\\033[34madduser hdfs
+adduser mapred
+adduser yarn
+addgroup hadoop
+usermod -aG hdfs,hadoop hdfs
+usermod -aG mapred,hadoop mapred
+usermod -aG yarn,hadoop yarn
+usermod -aG hdfs,hadoop hadoop
+groupadd docker
+usermod -aG docker yarn
+usermod -aG docker hadoop\\033[0m\\n"
+
+ echo -e "check docker user group ..."
+ # check user group
+ DOCKER_USER_GROUP='docker'
+
+ if ! grep -E "^${DOCKER_USER_GROUP}" /etc/group >& /dev/null
+ then
+ echo -e "user group ${DOCKER_USER_GROUP} does not exist, Please execute the following command:"
+ echo -e "\\033[34mgroupadd $DOCKER_USER_GROUP\\033[0m"
+ fi
+
+ # check user
+ USER_GROUP=(yarn hadoop)
+ for user in "${USER_GROUP[@]}"
+ do
+ if ! grep -E "^${user}" /etc/passwd >& /dev/null
+ then
+ echo -e "User ${user} does not exist, Please execute the following command:"
+ echo -e "\\033[34madduser ${user}\\033[0m"
+ echo -e "\\033[34musermod -aG ${DOCKER_USER_GROUP} ${user}\\033[0m"
+ fi
+
+ echo -e "Please execute the following command:"
+ echo -e "\\033[34musermod -aG ${DOCKER_USER_GROUP} ${user}\\033[0m"
+ done
+}
+
+## @description Some preparatory work for nvidia driver installation
+## @audience public
+## @stability stable
+function prepare_nvidia_environment()
+{
+ echo "prepare nvidia environment ..."
+
+ yum install "kernel-devel-$(uname -r)" "kernel-headers-$(uname -r)"
+
+ yum -y install epel-release
+ yum -y install dkms
+
+ echo -e "\\033[34m ===== Please manually execute the following command =====
+# 1. Disable nouveau
+# Add the content 'rd.driver.blacklist=nouveau nouveau.modeset=0'
+# to the 'GRUB_CMDLINE_LINUX' configuration item in the /etc/default/grub file.
+root:> vi /etc/default/grub
+vi:> GRUB_CMDLINE_LINUX=\"rd.driver.blacklist=nouveau nouveau.modeset=0 ...\"
+
+# 2. Generate configuration
+root:> grub2-mkconfig -o /boot/grub2/grub.cfg
+
+# 3. Open (new) /etc/modprobe.d/blacklist.conf, add content 'blacklist nouveau'
+root:> vi /etc/modprobe.d/blacklist.conf
+vi:> blacklist nouveau
+
+# 4. Update configuration and reboot
+root:> mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r)-nouveau.img
+root:> dracut /boot/initramfs-$(uname -r).img $(uname -r)
+root:> reboot
+\\033[0m"
+}
diff --git a/dev-support/submarine-installer/scripts/etcd.sh b/dev-support/submarine-installer/scripts/etcd.sh
new file mode 100644
index 0000000000000000000000000000000000000000..00bb10ccace8450b6889bbddc07ee0ea15dec17b
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/etcd.sh
@@ -0,0 +1,152 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description download etcd bin
+## @audience public
+## @stability stable
+function download_etcd_bin()
+{
+ # my download http server
+ if [[ -n "$DOWNLOAD_HTTP" ]]; then
+ MY_ETCD_DOWNLOAD_URL="${DOWNLOAD_HTTP}/downloads/etcd/${ETCD_TAR_GZ}"
+ else
+ MY_ETCD_DOWNLOAD_URL=${ETCD_DOWNLOAD_URL}
+ fi
+
+ if [[ -f "${DOWNLOAD_DIR}/etcd/${ETCD_TAR_GZ}" ]]; then
+ echo "${DOWNLOAD_DIR}/etcd/${ETCD_TAR_GZ} already exists."
+ else
+ echo "download ${MY_ETCD_DOWNLOAD_URL} ..."
+ wget -P "${DOWNLOAD_DIR}/etcd" "${MY_ETCD_DOWNLOAD_URL}"
+ fi
+}
+
+## @description install etcd bin
+## @audience public
+## @stability stable
+function install_etcd_bin()
+{
+ download_etcd_bin
+
+ # install etcd bin
+ mkdir -p "${INSTALL_TEMP_DIR}"
+ rm -rf "${INSTALL_TEMP_DIR}/etcd-*-linux-amd6"
+ tar zxvf "${DOWNLOAD_DIR}/etcd/${ETCD_TAR_GZ}" -C "${INSTALL_TEMP_DIR}"
+
+ cp -f "${INSTALL_TEMP_DIR}/etcd-${ETCD_VERSION}-linux-amd64/etcd" /usr/bin
+ cp -f "${INSTALL_TEMP_DIR}/etcd-${ETCD_VERSION}-linux-amd64/etcdctl" /usr/bin
+
+ mkdir -p /var/lib/etcd
+ chmod -R a+rw /var/lib/etcd
+}
+
+## @description install etcd config
+## @audience public
+## @stability stable
+function install_etcd_config()
+{
+ # config etcd.service
+ rm -rf "${INSTALL_TEMP_DIR}/etcd"
+ cp -rf "${PACKAGE_DIR}/etcd" "${INSTALL_TEMP_DIR}/"
+
+ # 1. Replace name with ETCD_NODE_NAME_REPLACE based on the location of the local IP in $ETCD_HOSTS
+ indexEtcdList=$(indexByEtcdHosts "${LOCAL_HOST_IP}")
+ # echo ${indexEtcdList}
+ etcdNodeName="etcdnode${indexEtcdList}"
+ # echo ${etcdNodeName}
+ sed -i "s/ETCD_NODE_NAME_REPLACE/${etcdNodeName}/g" "$INSTALL_TEMP_DIR/etcd/etcd.service"
+
+ # 2. Replace local IP address
+ sed -i "s/LOCAL_HOST_REPLACE/${LOCAL_HOST_IP}/g" "$INSTALL_TEMP_DIR/etcd/etcd.service"
+
+ # 3. Replace the initial-cluster parameter
+ # --initial-cluster=etcdnode1=http://10.196.69.173:2380,etcdnode2=http://10.196.69.174:2380,etcdnode3=http://10.196.69.175:2380 \
+ initialCluster=''
+ index=0
+ etcdHostsSize=${#ETCD_HOSTS[@]}
+ for item in "${ETCD_HOSTS[@]}"
+ do
+ # char '/' need to escape '\\/'
+ initialCluster="${initialCluster}etcdnode${index}=http:\\/\\/${item}:2380"
+ if [[ ${index} -lt ${etcdHostsSize}-1 ]]; then
+ initialCluster=${initialCluster}","
+ fi
+ index=$((index+1))
+ done
+ #echo "initialCluster=${initialCluster}"
+ sed -i "s/INITIAL_CLUSTER_REPLACE/${initialCluster}/g" "$INSTALL_TEMP_DIR/etcd/etcd.service"
+
+ cp "$INSTALL_TEMP_DIR/etcd/etcd.service" /etc/systemd/system/
+}
+
+## @description install etcd
+## @audience public
+## @stability stable
+function install_etcd()
+{
+ index=$(indexByEtcdHosts "${LOCAL_HOST_IP}")
+ if [ -z "$index" ]; then
+ echo -e "STOP: This host\\033[31m[${LOCAL_HOST_IP}]\\033[0m is not in the ETCD server list\\033[31m[${ETCD_HOSTS[*]}]\\033[0m"
+ return 1
+ fi
+
+ install_etcd_bin
+
+ install_etcd_config
+
+ systemctl daemon-reload
+ systemctl enable etcd.service
+}
+
+## @description uninstall etcd
+## @audience public
+## @stability stable
+function uninstall_etcd()
+{
+ echo "stop etcd.service"
+ systemctl stop etcd.service
+
+ echo "rm etcd ..."
+ rm /usr/bin/etcd
+ rm /usr/bin/etcdctl
+ rm -rf /var/lib/etcd
+ rm /etc/systemd/system/etcd.service
+
+ systemctl daemon-reload
+}
+
+## @description start etcd
+## @audience public
+## @stability stable
+function start_etcd()
+{
+ systemctl restart etcd.service
+
+ echo " ===== Check the status of the etcd service ====="
+ echo " exec etcdctl cluster-health"
+ etcdctl cluster-health
+ echo " exec etcdctl cluster-health"
+ etcdctl member list
+}
+
+## @description stop etcd
+## @audience public
+## @stability stable
+function stop_etcd()
+{
+ systemctl stop etcd.service
+}
diff --git a/dev-support/submarine-installer/scripts/menu.sh b/dev-support/submarine-installer/scripts/menu.sh
new file mode 100644
index 0000000000000000000000000000000000000000..aff9d7a67d3446f02cee1ed0c6f4034e5979c3ac
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/menu.sh
@@ -0,0 +1,561 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description main menu
+## @audience public
+## @stability stable
+main_menu()
+{
+cat< [prepare system environment]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.prepare operation system\\e[0m"
+echo -e " \\e[32m2.prepare operation system kernel\\e[0m"
+echo -e " \\e[32m3.prepare GCC version\\e[0m"
+echo -e " \\e[32m4.check GPU\\e[0m"
+echo -e " \\e[32m5.prepare user&group\\e[0m"
+echo -e " \\e[32m6.prepare nvidia environment\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [install component]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.install etcd\\e[0m"
+echo -e " \\e[32m2.install docker\\e[0m"
+echo -e " \\e[32m3.install calico network\\e[0m"
+echo -e " \\e[32m4.install nvidia driver\\e[0m"
+echo -e " \\e[32m5.install nvidia docker\\e[0m"
+echo -e " \\e[32m6.install submarine autorun script\\e[0m"
+echo -e " \\e[32m7.install yarn\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [uninstall component]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.uninstall etcd\\e[0m"
+echo -e " \\e[32m2.uninstall docker\\e[0m"
+echo -e " \\e[32m3.uninstall calico network\\e[0m"
+echo -e " \\e[32m4.uninstall nvidia driver\\e[0m"
+echo -e " \\e[32m5.uninstall nvidia docker\\e[0m"
+echo -e " \\e[32m6.uninstall submarine autorun script\\e[0m"
+echo -e " \\e[32m7.uninstall yarn\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [start component]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.start etcd\\e[0m"
+echo -e " \\e[32m2.start docker\\e[0m"
+echo -e " \\e[32m3.start calico network\\e[0m"
+echo -e " \\e[32m4.start yarn\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [stop component]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.stop etcd\\e[0m"
+echo -e " \\e[32m2.stop docker\\e[0m"
+echo -e " \\e[32m3.stop calico network\\e[0m"
+echo -e " \\e[32m4.stop yarn\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [install yarn]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.install YARN [every host]\\e[0m"
+echo -e " \\e[32m2.install YARN container-executor [every host]\\e[0m"
+echo -e " \\e[32m3.install YARN Timeline [one host]\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< [install yarn]
+------------------------------------------------------------------------------------
+MENULIST
+echo -e " \\e[32m1.uninstall Yarn\\e[0m"
+echo -e ""
+echo -e " \\e[32mb.back main menu\\e[0m"
+cat< Failed to download nvidia-docker.
+ Please specify nvidia component for download_and_uncompress_nvidia_repo \\033[0m"
+ return 1
+ fi
+ local component=$1
+
+ if [[ -d "${DOWNLOAD_DIR}/nvidia-docker-repo/${component}/centos7" ]]; then
+ echo "${DOWNLOAD_DIR}/nvidia-docker-repo/${component}/centos7 already exists."
+ else
+ # Trim the last slash of NVIDIA_DOCKER_GIT_SNAPSHOT_URL
+ local NVIDIA_DOCKER_URL="$(echo -e "${NVIDIA_DOCKER_GIT_SNAPSHOT_URL}" | sed -e 's/\/*$//')"
+ wget ${NVIDIA_DOCKER_URL}/${component}/tarball/gh-pages -O - | \
+ tar -zx --strip-components=1 -C ${DOWNLOAD_DIR}/nvidia-docker-repo/${component}
+ if [[ $? -ne 0 ]]; then
+ echo -e "\\033[32mshell:> Failed to download ${component} of nvidia-docker
+ from ${NVIDIA_DOCKER_URL}/${component}/tarball/gh-pages \\033[0m"
+ fi
+ fi
+}
+
+## @description install nvidia docker
+## @audience public
+## @stability stable
+function install_nvidia_docker()
+{
+ # Backup /etc/docker/daemon.json
+ local DOCKER_DAEMON_BAK="${DOWNLOAD_DIR}/docker-daemon-bak"
+ if [[ ! -d "${DOCKER_DAEMON_BAK}" ]]; then
+ mkdir -p "${DOCKER_DAEMON_BAK}"
+ fi
+ cp /etc/docker/daemon.json "${DOCKER_DAEMON_BAK}"
+ echo "Backup /etc/docker/daemon.json in ${DOCKER_DAEMON_BAK}"
+
+ # Remove nvidia docker 1.0
+ remove_nvidia_docker_1.0
+
+ # Get nvidia-docker repo
+ if [[ ! -d "${DOWNLOAD_DIR}/nvidia-docker-repo" ]]; then
+ mkdir -p "${DOWNLOAD_DIR}/nvidia-docker-repo"
+ fi
+ local dockerRepo="${DOWNLOAD_DIR}/nvidia-docker-repo/nvidia-docker.repo"
+ if [[ -n "$DOWNLOAD_HTTP" ]]; then
+ wget -P "${DOWNLOAD_DIR}/nvidia-docker-repo/" \
+ "${DOWNLOAD_HTTP}/downloads/nvidia-docker-repo/nvidia-docker/centos7/nvidia-docker.repo"
+ local DOWNLOAD_HTTP_REGEX=$(echo ${DOWNLOAD_HTTP} | sed 's/\//\\\//g')
+ echo "DOWNLOAD_HTTP_REGEX: ${DOWNLOAD_HTTP_REGEX}"
+ sed -i "s/https:\/\/nvidia.github.io/${DOWNLOAD_HTTP_REGEX}\/downloads\/nvidia-docker-repo/g" \
+ "${dockerRepo}"
+ else
+ download_nvidia_docker_bin
+ local DOWNLOAD_DIR_REGEX=$(echo "${DOWNLOAD_DIR}" | sed 's/\//\\\//g')
+ cp "${DOWNLOAD_DIR}/nvidia-docker-repo/nvidia-docker/centos7/nvidia-docker.repo" \
+ "${dockerRepo}"
+ sed -i "s/https:\/\/nvidia.github.io/file:\/\/${DOWNLOAD_DIR_REGEX}\/nvidia-docker-repo/g" \
+ "${dockerRepo}"
+ fi
+
+ # Install nvidia-docker
+ sudo cp ${dockerRepo} /etc/yum.repos.d/nvidia-docker.repo
+ echo -e "\\033[31m Installing nvidia-docker2 ...\\033[0m"
+ sudo yum install -y nvidia-docker2-${NVIDIA_DOCKER_VERSION}-1.docker${DOCKER_VERSION_NUM}
+
+ # As nvidia-docker would overwrite daemon.json, append old daemon.json into the now daemon.json
+ COMBINE_JSON="${SCRIPTS_DIR}/combine-docker-daemons.py"
+ IS_NEW_JSON=$(python ${COMBINE_JSON} ${DOCKER_DAEMON_BAK}/daemon.json /etc/docker/daemon.json ${DOCKER_DAEMON_BAK}/daemon-new.json)
+ if [[ "${IS_NEW_JSON}" = "True" ]]; then
+ sudo cp ${DOCKER_DAEMON_BAK}/daemon-new.json /etc/docker/daemon.json
+ echo "Succeed to update /etc/docker/daemon.json"
+ else
+ echo "WARNING: /etc/docker/daemon.json is overrided by nvidia-docker and
+ can't be merged with the old daemon.json. Please update it manually
+ later."
+ fi
+
+ # create nvidia driver library path
+ if [ ! -d "/var/lib/nvidia-docker/volumes/nvidia_driver" ]; then
+ echo "WARN: /var/lib/nvidia-docker/volumes/nvidia_driver folder path is not exist!"
+ sudo mkdir -p /var/lib/nvidia-docker/volumes/nvidia_driver
+ fi
+
+ local nvidiaVersion
+ nvidiaVersion=$(get_nvidia_version)
+ echo -e "\\033[31m nvidia detect version is ${nvidiaVersion}\\033[0m"
+
+ sudo mkdir "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}"
+ sudo mkdir "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}/bin"
+ sudo mkdir "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}/lib64"
+
+ sudo cp /usr/bin/nvidia* "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}/bin"
+ sudo cp /usr/lib64/libcuda* "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}/lib64"
+ sudo cp /usr/lib64/libnvidia* "/var/lib/nvidia-docker/volumes/nvidia_driver/${nvidiaVersion}/lib64"
+
+ echo -e "\\033[32m===== Please manually execute the following command =====\\033[0m"
+ echo -e "\\033[32mshell:> nvidia-docker run --rm ${DOCKER_REGISTRY}/nvidia/cuda:9.0-devel nvidia-smi
+# If you don't see the list of graphics cards above, the NVIDIA driver installation failed. =====
+\\033[0m"
+
+ echo -e "\\033[32m===== Please manually execute the following command =====\\033[0m"
+ echo -e "\\033[32m# Test with tf.test.is_gpu_available()
+shell:> nvidia-docker run -it ${DOCKER_REGISTRY}/tensorflow/tensorflow:1.9.0-gpu bash
+# In docker container
+container:> python
+python:> import tensorflow as tf
+python:> tf.test.is_gpu_available()
+python:> exit()
+\\033[0m"
+}
+
+## @description uninstall nvidia docker
+## @audience public
+## @stability stable
+function uninstall_nvidia_docker()
+{
+ sudo yum remove -y nvidia-docker2-${NVIDIA_DOCKER_VERSION}-1.docker${DOCKER_VERSION_NUM}
+}
+
+## @description uninstall nvidia docker 1.0
+## @audience public
+## @stability stable
+function remove_nvidia_docker_1.0()
+{
+ docker volume ls -q -f driver=nvidia-docker | \
+ xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
+ sudo yum remove nvidia-docker
+}
diff --git a/dev-support/submarine-installer/scripts/nvidia.sh b/dev-support/submarine-installer/scripts/nvidia.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a335214eacea1694aa1b87df22d9f5d71245981d
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/nvidia.sh
@@ -0,0 +1,155 @@
+#!/usr/bin/env bash
+# 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.
+
+nvidia_run_file=""
+
+## @description get nvidia version
+## @audience public
+## @stability stable
+function get_nvidia_version()
+{
+ local nvidia_detect_info
+ nvidia_detect_info=$("nvidia-detect" -v)
+ echo $nvidia_detect_info | sed "s/^.*This device requires the current \([0-9.]*\).*/\1/"
+}
+
+## @description download nvidia detect
+## @audience public
+## @stability stable
+function download_nvidia_detect_rpm()
+{
+ if [[ -f ${DOWNLOAD_DIR}/nvidia/nvidia-detect.rpm ]]; then
+ echo "NVIDIA nvidia-detect.rpm already exists ${DOWNLOAD_DIR}/nvidia/ directory."
+ echo "===== Please make sure the ${DOWNLOAD_DIR}/nvidia/nvidia-detect.rpm file is complete and can be used normally. ====="
+ elif [[ -n "$DOWNLOAD_HTTP" ]]; then
+ # Get nvidia-detect.rpm from download server
+ echo "Download ${MY_NVIDIA_DETECT_URL} ..."
+ wget -P "${DOWNLOAD_DIR}/nvidia/" "${DOWNLOAD_HTTP}/downloads/nvidia/nvidia-detect.rpm"
+ if [[ $? -ne 0 ]]; then
+ echo -e "\\033[32mshell:> Failed to download nvidia-detect.rpm of nvidia
+ detect from ${DOWNLOAD_HTTP}/downloads/nvidia/nvidia-detect.rpm \\033[0m"
+ fi
+ else
+ nvidiaDetectRpm=`curl --silent ${NVIDIA_DETECT_URL} | grep nvidia-detect- | sed 's/.*\(nvidia-detect-.*.rpm\).*/\1/g' | head -n 1`
+ # Trim the last slash of DOCKER_REPO
+ NVIDIA_DETECT_URL_TRIMED="$(echo -e "${NVIDIA_DETECT_URL}" | sed -e 's/\/*$//')"
+ wget --output-document="${DOWNLOAD_DIR}/nvidia/nvidia-detect.rpm" "${NVIDIA_DETECT_URL_TRIMED}/${nvidiaDetectRpm}"
+ if [[ $? -ne 0 ]]; then
+ echo -e "\\033[32mshell:> Failed to download nvidia-detect.rpm of nvidia
+ detect from ${NVIDIA_DETECT_URL}/${nvidiaDetectRpm} \\033[0m"
+ fi
+ fi
+}
+
+## @description download nvidia driver
+## @audience public
+## @stability stable
+function download_nvidia_driver()
+{
+ download_nvidia_detect_rpm
+
+ # Install nvidia detect if needed
+ if ! [ -x "$(command -v nvidia-detect)" ]; then
+ echo 'Installing nvidia-detect ...'
+ sudo rpm -ivh "${DOWNLOAD_DIR}/nvidia/nvidia-detect.rpm"
+ fi
+
+ echo "Check the gpu cards with nvidia-detect ..."
+ local nvidiaVersion
+ if [[ ${IS_DOWNLOAD_SERVER} && -n ${NVIDIA_DRIVER_VERSION} ]]; then
+ nvidiaVersion=${NVIDIA_DRIVER_VERSION}
+ else
+ nvidiaVersion=$(get_nvidia_version)
+ fi
+ echo -e "detect nvidia version is \\033[31m${nvidiaVersion}\\033[0m"
+
+ # download NVIDIA driver
+ if [[ "$nvidiaVersion" = "" ]]; then
+ echo -e "\\033[31mERROR: No graphics card device detected.\\033[0m"
+ return 1
+ else
+ nvidia_run_file="NVIDIA-Linux-x86_64-${nvidiaVersion}.run"
+
+ # submarine http server
+ if [[ -n "$DOWNLOAD_HTTP" ]]; then
+ MY_NVIDIA_DRIVER_RUN_URL="${DOWNLOAD_HTTP}/downloads/nvidia/${nvidia_run_file}"
+ else
+ # http://us.download.nvidia.com/XFree86/Linux-x86_64/390.87/NVIDIA-Linux-x86_64-390.87.run
+ MY_NVIDIA_DRIVER_RUN_URL="http://us.download.nvidia.com/XFree86/Linux-x86_64/${nvidiaVersion}/${nvidia_run_file}"
+ fi
+
+ if [[ -f ${DOWNLOAD_DIR}/nvidia/${nvidia_run_file} ]]; then
+ echo "NVIDIA driver files already exist in the ${DOWNLOAD_DIR}/nvidia/${nvidia_run_file} directory."
+ echo "===== Please make sure the ${DOWNLOAD_DIR}/nvidia/nvidia/${nvidia_run_file} file is complete and can be used normally. ====="
+ else
+ echo "Download the NVIDIA driver from the ${MY_NVIDIA_DRIVER_RUN_URL}"
+ wget -P "${DOWNLOAD_DIR}/nvidia/" "${MY_NVIDIA_DRIVER_RUN_URL}"
+ fi
+ fi
+}
+
+## @description install nvidia
+## @audience public
+## @stability stable
+function install_nvidia()
+{
+ download_nvidia_driver
+
+ # Confirm that the system disables nouveau
+ local disable_nouveau_info
+ disable_nouveau_info=$(lsmod | grep nouveau)
+ if [[ "$disable_nouveau_info" = "" ]]; then
+ echo "===== Start installing the NVIDIA driver ====="
+ echo -e "Some options during the installation
+ Would you like to register the kernel module sources with DKMS?
+ This will allow DKMS to automatically build a new module, if you install a different kernel later.
+ \\033[33m[Yes]\\033[0m
+ Install NVIDIA's 32-bit compatibility libraries \\033[33m[Yes]\\033[0m
+ centos Install NVIDIA's 32-bit compatibility libraries
+ \\033[33m[Yes]\\033[0m
+ Would you like to run the nvidia-xconfig utility to automatically update your X configuration file...
+ \\033[33m[No]\\033[0m"
+ sleep 2
+ sh "${DOWNLOAD_DIR}/nvidia/${nvidia_run_file}"
+ else
+ echo -e "ERROR: Nouveau is not disabled"
+ return 1
+ fi
+
+ echo -e "\\033[32m===== execute nvidia-smi. You should be able to see the list of graphics cards =====\\033[0m"
+ sleep 1
+ nvidia-smi
+}
+
+## @description uninstall nvidia
+## @audience public
+## @stability stable
+function uninstall_nvidia()
+{
+ if [ -x "$(command -v nvidia-detect)" ]; then
+ sudo yum remove nvidia-detect
+ echo "Succeeded to remove nvidia-detect"
+ fi
+
+ if [ ! -f "/usr/bin/nvidia-uninstall" ]; then
+ echo -e "\\033[31mERROR: /usr/bin/nvidia-uninstall file is not exist!\\033[0m"
+ return 1
+ fi
+
+ echo -e "execute /usr/bin/nvidia-uninstall"
+ sudo /usr/bin/nvidia-uninstall
+}
diff --git a/dev-support/submarine-installer/scripts/submarine.sh b/dev-support/submarine-installer/scripts/submarine.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f3baec2e90d8752a342b90b6718444c201bf8bf8
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/submarine.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description install submarine autorun script
+## @audience public
+## @stability stable
+function install_submarine()
+{
+ cp "${PACKAGE_DIR}/submarine/submarine.sh" /etc/rc.d/init.d/submarine.sh
+ chmod +x /etc/rc.d/init.d/submarine.sh
+ chmod +x /etc/rc.d/rc.local
+
+ if [ "$(grep -c "/etc/rc.d/init.d/submarine.sh" /etc/rc.d/rc.local)" -eq '0' ]; then
+ echo "/etc/rc.d/init.d/submarine.sh">> /etc/rc.d/rc.local
+ fi
+}
+
+## @description uninstall submarine autorun script
+## @audience public
+## @stability stable
+function uninstall_submarine()
+{
+ rm /etc/rc.d/init.d/submarine.sh
+}
\ No newline at end of file
diff --git a/dev-support/submarine-installer/scripts/utils.sh b/dev-support/submarine-installer/scripts/utils.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b3ecbcb371220a0228aea845f59133c89a9a000e
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/utils.sh
@@ -0,0 +1,204 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description check install user
+## @audience public
+## @stability stable
+function check_install_user()
+{
+ if [[ $(id -u) -ne 0 ]];then
+ echo "This script must be run with a ROOT user!"
+ exit # don't call exit_install()
+ fi
+}
+
+## @description exit install
+## @audience public
+## @stability stable
+function exit_install()
+{
+ echo "Exit the installation!"
+ exit
+}
+
+## @description Check if the IP address format is correct
+## @audience public
+## @stability stable
+function valid_ip()
+{
+ local ip=$1
+ local stat=1
+
+ if [[ $ip =~ ^[0-9]{1,3\}.[0-9]{1,3\}.[0-9]{1,3\}.[0-9]{1,3\}$ ]]; then
+ OIFS=$IFS
+ IFS='.'
+ ip=($ip)
+ IFS=$OIFS
+
+ if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
+ stat=$?
+ fi
+ fi
+
+ return $stat
+}
+
+## @description Check if the configuration file configuration is correct
+## @audience public
+## @stability stable
+function check_install_conf()
+{
+ echo "Check if the configuration file configuration is correct ..."
+
+ # check YARN_SECURITY's value
+ if [ -z "${YARN_SECURITY}" ]; then
+ echo "YARN_SECURITY=[$YARN_SECURITY] is empty! please use true or false "
+ exit_install
+ fi
+
+ # check resource manager
+ rmCount=${#YARN_RESOURCE_MANAGER_HOSTS[@]}
+ if [[ $rmCount -gt 2 ]]; then # <>2
+ echo "Number of resource manager nodes = [$rmCount], must be configured equal 2 servers! "
+ exit_install
+ fi
+
+ #
+ if [ -z "${YARN_REGISTRY_DNS_HOST_PORT}" ]; then
+ echo "YARN_REGISTRY_DNS_HOST_PORT=[$YARN_REGISTRY_DNS_HOST_PORT] is empty! "
+ exit_install
+ fi
+
+ # Check if it is empty
+ if [[ "${YARN_SECURITY}" = "true" && -z "${LOCAL_REALM}" ]]; then
+ echo "LOCAL_REALM=[$LOCAL_REALM] can not be empty! "
+ exit_install
+ fi
+
+ if [[ "${YARN_SECURITY}" = "true" && -z "${HADOOP_KEYTAB_LOCATION}" ]]; then
+ echo "HADOOP_KEYTAB_LOCATION=[$HADOOP_KEYTAB_LOCATION] can not be empty! "
+ exit_install
+ fi
+
+ if [[ "${YARN_SECURITY}" = "true" && -z "${HADOOP_PRINCIPAL}" ]]; then
+ echo "HADOOP_PRINCIPAL=[$HADOOP_PRINCIPAL] can not be empty! "
+ exit_install
+ fi
+
+ if [[ "${YARN_SECURITY}" = "true" && -z "${MAPRED_KEYTAB_LOCATION}" ]]; then
+ echo "MAPRED_KEYTAB_LOCATION=[$MAPRED_KEYTAB_LOCATION] can not be empty! "
+ exit_install
+ fi
+
+ if [[ "${YARN_SECURITY}" = "true" && -z "${YARN_KEYTAB_LOCATION}" ]]; then
+ echo "YARN_KEYTAB_LOCATION=[$YARN_KEYTAB_LOCATION] can not be empty! "
+ exit_install
+ fi
+
+ if [[ "${YARN_SECURITY}" = "true" && -z "${HTTP_KEYTAB_LOCATION}" ]]; then
+ echo "HTTP_KEYTAB_LOCATION=[$HTTP_KEYTAB_LOCATION] can not be empty! "
+ exit_install
+ fi
+
+ # check etcd conf
+ hostCount=${#ETCD_HOSTS[@]}
+ if [[ $hostCount -lt 3 && hostCount -ne 0 ]]; then # <>2
+ echo "Number of nodes = [$hostCount], must be configured to be greater than or equal to 3 servers! "
+ exit_install
+ fi
+ echo "Check if the configuration file configuration is correct [ Done ]"
+}
+
+## @description index by EtcdHosts list
+## @audience public
+## @stability stable
+function indexByEtcdHosts() {
+ index=0
+ while [ "$index" -lt "${#ETCD_HOSTS[@]}" ]; do
+ if [ "${ETCD_HOSTS[$index]}" = "$1" ]; then
+ echo $index
+ return
+ fi
+ (( index++ ))
+ done
+ echo ""
+}
+
+## @description index by Resource Manager Hosts list
+## @audience public
+## @stability stable
+function indexByRMHosts() {
+ index=0
+ while [ "$index" -lt "${#YARN_RESOURCE_MANAGER_HOSTS[@]}" ]; do
+ if [ "${YARN_RESOURCE_MANAGER_HOSTS[$index]}" = "$1" ]; then
+ echo $index
+ return
+ fi
+ (( index++ ))
+ done
+ echo ""
+}
+
+## @description index of node manager exclude Hosts list
+## @audience public
+## @stability stable
+function indexOfNMExcludeHosts() {
+ index=0
+ while [ "$index" -lt "${#YARN_NODE_MANAGER_EXCLUDE_HOSTS[@]}" ]; do
+ if [ "${YARN_NODE_MANAGER_EXCLUDE_HOSTS[$index]}" = "$1" ]; then
+ echo $index
+ return
+ fi
+ (( index++ ))
+ done
+ echo ""
+}
+
+## @description index by Resource Manager Hosts list
+## @audience public
+## @stability stable
+function pathExitsOnHDFS() {
+ exists=$("${HADOOP_HOME}/bin/hadoop" dfs -ls -d "$1")
+ echo "${exists}"
+}
+
+## @description get local IP
+## @audience public
+## @stability stable
+function getLocalIP()
+{
+ local _ip _myip _line _nl=$'\n'
+ while IFS=$': \t' read -r -a _line ;do
+ [ -z "${_line%inet}" ] &&
+ _ip=${_line[${#_line[1]}>4?1:2]} &&
+ [ "${_ip#127.0.0.1}" ] && _myip=$_ip
+ done< <(LANG=C /sbin/ifconfig)
+ printf "%s" ${1+-v} "$1" "%s${_nl:0:$((${#1}>0?0:1))}" "$_myip"
+}
+
+## @description get ip list
+## @audience public
+## @stability stable
+function get_ip_list()
+{
+ array=$(ip -o -4 addr | awk '{print $4}' | grep -v 127 | cut -d/ -f1)
+
+ for ip in "${array[@]}"
+ do
+ LOCAL_HOST_IP_LIST+=(${ip})
+ done
+}
diff --git a/dev-support/submarine-installer/scripts/xmlcombine.py b/dev-support/submarine-installer/scripts/xmlcombine.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b049d02069e6c9f853207c253e9aa28e93d43f9
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/xmlcombine.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# 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.
+
+import sys
+from xml.etree import ElementTree
+
+def run(files):
+ first = None
+ for filename in files:
+ data = ElementTree.parse(filename).getroot()
+ if first is None:
+ first = data
+ else:
+ first.extend(data)
+ if first is not None:
+ print ElementTree.tostring(first)
+
+if __name__ == "__main__":
+ run(sys.argv[1:])
diff --git a/dev-support/submarine-installer/scripts/yarn.sh b/dev-support/submarine-installer/scripts/yarn.sh
new file mode 100644
index 0000000000000000000000000000000000000000..461c20e3ab027effaa17c0878cd77537e6dcb338
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/yarn.sh
@@ -0,0 +1,640 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description install yarn
+## @audience public
+## @stability stable
+function install_yarn()
+{
+ # base YARN_SECURITY determine which etc is
+ rm -f ${PACKAGE_DIR}/hadoop/yarn/etc
+ ln -s ${PACKAGE_DIR}/hadoop/yarn/etc_secure ${PACKAGE_DIR}/hadoop/yarn/etc
+
+ initialize_temp
+
+ host=$(hostname)
+ index=$(indexByRMHosts "${host}")
+ if [[ -n "$index" || "x$YARN_TIMELINE_HOST" != "x$host" ]]; then
+ kinit -kt ${HADOOP_KEYTAB_LOCATION} ${HADOOP_PRINCIPAL}
+ fi
+
+ install_java_tarball
+ if [[ $? = 1 ]]; then
+ return 1
+ fi
+ install_yarn_tarball
+ if [[ $? = 1 ]]; then
+ return 1
+ fi
+ install_yarn_sbin
+ install_yarn_rm_nm
+ install_yarn_service
+ install_registry_dns
+ install_timeline_server
+ install_job_history
+ install_mapred
+ install_spark_shuffle
+ install_lzo_native
+
+ # copy file
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/hdfs-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/capacity-scheduler.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/resource-types.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/log4j.properties" "${HADOOP_HOME}/etc/hadoop/"
+ chown "${HADOOP_SETUP_USER}":yarn "${HADOOP_HOME}"/etc/hadoop/*
+}
+
+## @description Initialize tmp dir for installation.
+## @audience public
+## @stability stable
+function initialize_temp()
+{
+ mkdir -p "${INSTALL_TEMP_DIR}/hadoop"
+ \cp -rf "${PACKAGE_DIR}/hadoop/yarn" "${INSTALL_TEMP_DIR}/hadoop"
+ isGpuEnabled=$(nvidia-smi)
+ if [[ -n "$isGpuEnabled" ]]; then
+ python ${SCRIPTS_DIR}/xmlcombine.py ${PACKAGE_DIR}/hadoop/yarn/etc/hadoop/yarn-site.xml ${PACKAGE_DIR}/hadoop/yarn/etc/hadoop/gpu/yarn-site-gpu.xml > "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ fi
+ chown -R ${HADOOP_SETUP_USER} "${INSTALL_TEMP_DIR}/hadoop"
+}
+
+## @description uninstall yarn
+## @audience public
+## @stability stable
+function uninstall_yarn()
+{
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ executor_conf_dir=$(dirname "${executor_dir}")/etc/hadoop
+
+ rm -rf "${YARN_CONTAINER_EXECUTOR_PATH}"
+ rm -rf "${executor_conf_dir}"
+ rm -rf "${HADOOP_HOME}"
+}
+
+## @description install yarn container executor
+## @audience public
+## @stability stable
+function install_yarn_container_executor()
+{
+ echo "install yarn container executor file ..."
+
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ if [ ! -d "${executor_dir}" ]; then
+ mkdir -p "${executor_dir}"
+ fi
+ if [ -f "${YARN_CONTAINER_EXECUTOR_PATH}" ]; then
+ if [ -f "${HADOOP_HOME}/bin/container-executor" ]; then
+ rm ${YARN_CONTAINER_EXECUTOR_PATH}
+ fi
+ fi
+
+ if [ -f "${HADOOP_HOME}/bin/container-executor" ]; then
+ cp -f "${HADOOP_HOME}/bin/container-executor" "${YARN_CONTAINER_EXECUTOR_PATH}"
+ rm "${HADOOP_HOME}/bin/container-executor"
+ fi
+
+ sudo chmod 6755 "${executor_dir}"
+ sudo chown :yarn "${YARN_CONTAINER_EXECUTOR_PATH}"
+ sudo chmod 6050 "${YARN_CONTAINER_EXECUTOR_PATH}"
+}
+
+## @description Deploy hadoop yarn tar ball
+## @audience public
+## @stability stable
+function install_yarn_tarball()
+{
+ tag=`date '+%Y%m%d%H%M%S'`
+ if [ -f "${PACKAGE_DIR}/hadoop/${HADOOP_TARBALL}" ]; then
+ tar -zxvf "${PACKAGE_DIR}/hadoop/${HADOOP_TARBALL}" -C "${PACKAGE_DIR}/hadoop/"
+ mv "${PACKAGE_DIR}/hadoop/${HADOOP_VERSION}" "/home/${HADOOP_SETUP_USER}/${HADOOP_VERSION}-${tag}"
+ chown -R ${HADOOP_SETUP_USER} "/home/hadoop/${HADOOP_VERSION}-${tag}"
+ if [[ -d "${HADOOP_HOME}" ]] || [[ -L "${HADOOP_HOME}" ]]; then
+ rm -rf ${HADOOP_HOME}
+ fi
+ ln -s "/home/hadoop/${HADOOP_VERSION}-${tag}" "${HADOOP_HOME}"
+ chown ${HADOOP_SETUP_USER} "${HADOOP_HOME}"
+ else
+ echo "ERROR: Please put ${HADOOP_TARBALL} in the path of ${PACKAGE_DIR}/hadoop/ firstly."
+ return 1
+ fi
+}
+
+## @description Deploy java tar ball
+## @audience public
+## @stability stable
+function install_java_tarball()
+{
+ if [[ -d "${JAVA_HOME}" ]] || [[ -L "${JAVA_HOME}" ]]; then
+ echo "JAVA_HOME already exists. There is no need to install java."
+ else
+ if [[ -f "${PACKAGE_DIR}/java/${JAVA_TARBALL}" ]]; then
+ tar -zxvf "${PACKAGE_DIR}/java/${JAVA_TARBALL}" -C "${PACKAGE_DIR}/java/"
+ mv "${PACKAGE_DIR}/java/${JAVA_VERSION}" "/home/${HADOOP_SETUP_USER}/${JAVA_VERSION}"
+ chown -R ${HADOOP_SETUP_USER} "/home/hadoop/${JAVA_VERSION}"
+ ln -s "/home/hadoop/${JAVA_VERSION}" "${JAVA_HOME}"
+ else
+ echo "Error: Failed to install java, please put java tarball in the path of
+ ${PACKAGE_DIR}/java/${JAVA_TARBALL}"
+ return 1
+ fi
+ fi
+}
+
+## @description install yarn resource & node manager
+## @audience public
+## @stability stable
+function install_yarn_rm_nm()
+{
+ echo "install yarn config file ..."
+ host=$(hostname)
+
+ find="/"
+ replace="\\/"
+ escape_yarn_nodemanager_local_dirs=${YARN_NODEMANAGER_LOCAL_DIRS//$find/$replace}
+ escape_yarn_nodemanager_log_dirs=${YARN_NODEMANAGER_LOG_DIRS//$find/$replace}
+ escape_yarn_keytab_location=${YARN_KEYTAB_LOCATION//$find/$replace}
+ escape_yarn_hierarchy=${YARN_HIERARCHY//$find/$replace}
+ escape_http_keytab_location=${HTTP_KEYTAB_LOCATION//$find/$replace}
+ escape_yarn_nodemanager_nodes_exclude_path=${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH//$find/$replace}
+ escape_yarn_nodemanager_recovery_dir=${YARN_NODEMANAGER_RECOVERY_DIR//$find/$replace}
+ escape_fs_defaults=${FS_DEFAULTFS//$find/$replace}
+ escape_hadoop_http_authentication_signature_secret_file=${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE//$find/$replace}
+ escape_hadoop_home=${HADOOP_HOME//$find/$replace}
+
+ # container-executor.cfg`
+ sed -i "s/YARN_NODEMANAGER_LOCAL_DIRS_REPLACE/${escape_yarn_nodemanager_local_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/YARN_NODEMANAGER_LOG_DIRS_REPLACE/${escape_yarn_nodemanager_log_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/DOCKER_REGISTRY_REPLACE/${DOCKER_REGISTRY}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS_REPLACE/${YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/YARN_HIERARCHY_REPLACE/${escape_yarn_hierarchy}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/HADOOP_HOME_REPLACE/${escape_hadoop_home}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+
+ # enable cgroup for yarn
+ . "${PACKAGE_DIR}/submarine/submarine.sh"
+
+ # Delete the ASF license comment in the container-executor.cfg file, otherwise it will cause a cfg format error.
+ sed -i '1,16d' "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ executor_conf_dir=$(dirname "${executor_dir}")/etc/hadoop
+ if [ ! -d "${executor_conf_dir}" ]; then
+ sudo mkdir -p "${executor_conf_dir}"
+ fi
+
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg" "${executor_conf_dir}"
+
+ # yarn-site.xml
+ sed -i "s/YARN_RESOURCE_MANAGER_HOSTS1_REPLACE/${YARN_RESOURCE_MANAGER_HOSTS[0]}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_RESOURCE_MANAGER_HOSTS2_REPLACE/${YARN_RESOURCE_MANAGER_HOSTS[1]}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/HTTP_KEYTAB_LOCATION_REPLACE/${escape_http_keytab_location}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/LOCAL_CLUSTER_ID_REPLACE/${LOCAL_CLUSTER_ID}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_NODEMANAGER_LOCAL_DIRS_REPLACE/${escape_yarn_nodemanager_local_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_NODEMANAGER_LOG_DIRS_REPLACE/${escape_yarn_nodemanager_log_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ # Make nodemanager local dirs if the host is not in YARN_NODE_MANAGER_EXCLUDE_HOSTS
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ arr=(${YARN_NODEMANAGER_LOCAL_DIRS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ mkdir -p "${arr[$index]}"
+ (( index++ ))
+ done
+
+ arr=(${YARN_NODEMANAGER_LOG_DIRS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ mkdir -p "${arr[$index]}"
+ (( index++ ))
+ done
+
+ arr=(${YARN_NODEMANAGER_LOCAL_HOME_PATHS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ chown -R yarn "${arr[$index]}"
+ (( index++ ))
+ done
+ fi
+
+ sed -i "s/YARN_ZK_ADDRESS_REPLACE/${YARN_ZK_ADDRESS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_KEYTAB_LOCATION_REPLACE/${escape_yarn_keytab_location}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_DOCKER_CONTAINER_DEFAULT_NETWORK_REPLACE/${YARN_DOCKER_CONTAINER_DEFAULT_NETWORK}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS_REPLACE/${YARN_DOCKER_ALLOWED_CONTAINER_NETWORKS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+
+ sed -i "s/YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH_REPLACE/${escape_yarn_nodemanager_nodes_exclude_path}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ node_exclude_dir=$(dirname "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}")
+ if [[ ! -d "${node_exclude_dir}" ]]; then
+ mkdir -p "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ fi
+ if [[ ! -f "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}" ]]; then
+ touch "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ chmod 777 "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ fi
+
+ sed -i "s/YARN_NODEMANAGER_RECOVERY_DIR_REPLACE/${escape_yarn_nodemanager_recovery_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ mkdir -p "${YARN_NODEMANAGER_RECOVERY_DIR}"
+ chmod 777 "${YARN_NODEMANAGER_RECOVERY_DIR}"
+
+ # core-site.xml
+ sed -i "s/LOCAL_REALM_REPLACE/${LOCAL_REALM}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+ sed -i "s/YARN_ZK_ADDRESS_REPLACE/${YARN_ZK_ADDRESS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+ sed -i "s/FS_DEFAULTFS_REPLACE/${escape_fs_defaults}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+ sed -i "s/HTTP_KEYTAB_LOCATION_REPLACE/${escape_http_keytab_location}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+
+ # WARN: ${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE} Can not be empty!
+ echo 'hello submarine' > "${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE}"
+ escape_hadoop_http_authentication_signature_secret_file=${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE//$find/$replace}
+ sed -i "s/HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_REPLACE/${escape_hadoop_http_authentication_signature_secret_file}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/hdfs-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+
+ install_yarn_container_executor
+}
+
+function install_spark_shuffle() {
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/spark* "${HADOOP_HOME}/share/hadoop/yarn/lib/"
+}
+
+function install_lzo_native() {
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/native/libgpl* "${HADOOP_HOME}/lib/native/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/yarn/lib/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/hdfs/lib/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/common/lib/"
+ if [ ! -d "${HADOOP_HOME}/share/hadoop/mapreduce/lib/" ]; then
+ mkdir -p "${HADOOP_HOME}/share/hadoop/mapreduce/lib/"
+ fi
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/mapreduce/lib/"
+}
+
+function install_mapred() {
+ find="/"
+ replace="\\/"
+ escape_mapred_keytab_location=${MAPRED_KEYTAB_LOCATION//$find/$replace}
+ escape_yarn_app_mapreduce_am_staging_dir=${YARN_APP_MAPREDUCE_AM_STAGING_DIR//$find/$replace}
+ escape_fs_defaults=${FS_DEFAULTFS//$find/$replace}
+
+ sed -i "s/FS_DEFAULTFS_REPLACE/${escape_fs_defaults}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+ sed -i "s/YARN_APP_MAPREDUCE_AM_STAGING_DIR_REPLACE/${escape_yarn_app_mapreduce_am_staging_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+ host=$(hostname)
+ index=$(indexByRMHosts "${host}")
+ if [[ -n "$index" ]]; then
+ # Only RM needs to execute the following code
+ pathExists=$(pathExitsOnHDFS "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}")
+ if [[ -z "${pathExists}" ]]; then
+ echo "Create hdfs path ${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -mkdir -p "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -chown yarn:hadoop "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -chmod 1777 "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ fi
+ fi
+ sed -i "s/MAPRED_KEYTAB_LOCATION_REPLACE/${escape_mapred_keytab_location}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+}
+
+function install_yarn_sbin() {
+ find="/"
+ replace="\\/"
+ escape_yarn_gc_log_dir=${YARN_GC_LOG_DIR//$find/$replace}
+ escape_java_home=${JAVA_HOME//$find/$replace}
+ escape_hadoop_home=${HADOOP_HOME//$find/$replace}
+ escape_yarn_pid_dir=${YARN_PID_DIR//$find/$replace}
+ escape_yarn_log_dir=${YARN_LOG_DIR//$find/$replace}
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/sbin/* "${HADOOP_HOME}/sbin/"
+ chown "${HADOOP_SETUP_USER}":yarn "${HADOOP_HOME}"/sbin/*
+
+ if [ ! -d "$YARN_GC_LOG_DIR" ]; then
+ mkdir -p "$YARN_GC_LOG_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_GC_LOG_DIR}"
+ chmod 775 "${YARN_GC_LOG_DIR}"
+ fi
+
+ if [ ! -d "$YARN_LOG_DIR" ]; then
+ mkdir -p "$YARN_LOG_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_LOG_DIR}"
+ chmod 775 "${YARN_LOG_DIR}"
+ fi
+
+ if [ ! -d "$YARN_PID_DIR" ]; then
+ mkdir -p "$YARN_PID_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_PID_DIR}"
+ chmod 775 "${YARN_PID_DIR}"
+ fi
+
+ sed -i "s/YARN_LOG_DIR_REPLACE/${escape_yarn_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/YARN_PID_DIR_REPLACE/${escape_yarn_pid_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/JAVA_HOME_REPLACE/${escape_java_home}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/HADOOP_HOME_REPLACE/${escape_hadoop_home}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/mapred-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/mapred-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+cat<
+hadoop.proxyuser.yarn.hosts
+*
+
+
+hadoop.proxyuser.yarn.groups
+*
+
+-----------------------------------------------------------------
+HELPINFO
+}
+
+function install_registry_dns() {
+ sed -i "s/YARN_REGISTRY_DNS_HOST_REPLACE/${YARN_REGISTRY_DNS_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_REGISTRY_DNS_HOST_PORT_REPLACE/${YARN_REGISTRY_DNS_HOST_PORT}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+}
+
+function install_job_history() {
+ sed -i "s/YARN_JOB_HISTORY_HOST_REPLACE/${YARN_JOB_HISTORY_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+}
+
+## @description install yarn timeline server
+## @audience public
+## @stability stable
+## http://hadoop.apache.org/docs/r3.1.0/hadoop-yarn/hadoop-yarn-site/TimelineServer.html
+function install_timeline_server()
+{
+ find="/"
+ replace="\\/"
+ escape_aggregated_log_dir=${YARN_AGGREGATED_LOG_DIR//$find/$replace}
+ escape_yarn_timeline_service_hbase_configuration_file=${YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE//$find/$replace}
+ escape_yarn_keytab_location=${YARN_KEYTAB_LOCATION//$find/$replace}
+ escape_yarn_timeline_fs_store_dir=${YARN_TIMELINE_FS_STORE_DIR//$find/$replace}
+ # timeline v1.5
+ escape_yarn_timeline_service_leveldb_state_store_path=${YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH//$find/$replace}
+
+ # set leveldb configuration
+ sed -i "s/YARN_KEYTAB_LOCATION_REPLACE/${escape_yarn_keytab_location}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_AGGREGATED_LOG_DIR_REPLACE/${escape_aggregated_log_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE_REPLACE/${escape_yarn_timeline_service_hbase_configuration_file}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ # timeline v1.5
+ sed -i "s/YARN_TIMELINE_HOST_REPLACE/${YARN_TIMELINE_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE/${escape_yarn_timeline_service_leveldb_state_store_path}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_FS_STORE_DIR_REPLACE/${escape_yarn_timeline_fs_store_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+
+ host=$(hostname)
+ if [ "x$YARN_TIMELINE_HOST" != "x$host" ]; then
+ return 0
+ fi
+
+ echo -n "Do you want to create hdfs directories for timelineserver[Y/N]?"
+ read -r answer
+ echo "$answer"
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Stop creating hdfs directories for timelineserver"
+ return 0
+ fi
+
+ echo "install yarn timeline server V1.5 ..."
+
+cat< grant 'yarn', 'RWC'
+> grant 'HTTP', 'R'
+HELPINFO
+ echo -n "Have you done the above operation[Y/N]?"
+ read -r answer
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Stop installing the timeline server V2"
+ return 0
+ fi
+
+ pathExists=$(pathExitsOnHDFS "/hbase")
+ if [[ -z "${pathExists}" ]]; then
+ "${HADOOP_HOME}/bin/hadoop" fs -mkdir -p "/hbase"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod -R 755 "/hbase"
+ fi
+
+ pathExists=$(pathExitsOnHDFS "/hbase/coprocessor")
+ if [[ -z "${pathExists}" ]]; then
+ "${HADOOP_HOME}/bin/hadoop" fs -mkdir -p "/hbase/coprocessor"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod -R 755 "/hbase/coprocessor"
+ fi
+
+ "${HADOOP_HOME}/bin/hadoop" fs -put "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-coprocessor-3.*.jar "/hbase/coprocessor/hadoop-yarn-server-timelineservice.jar"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod 755 "/hbase/coprocessor/hadoop-yarn-server-timelineservice.jar"
+
+cat</lib path:
+HELPINFO
+
+ if [[ -n "${HBASE_HOME}" ]]; then
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-common-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-client-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ fi
+
+cat< path, Execute the following command to create a schema
+> bin/hbase org.apache.hadoop.yarn.server.timelineservice.storage.TimelineSchemaCreator -create
+HELPINFO
+ echo -n "Have you done the above operation[Y/N]?"
+ read -r answer
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Please initialize hbase timeline schema before you start timelineserver"
+ fi
+}
+
+## @description start yarn
+## @audience public
+## @stability stable
+function start_yarn()
+{
+ current_user=$(whoami)
+ host=$(hostname)
+
+ # Start RM if the host is in YARN_RESOURCE_MANAGER_HOSTS
+ index=$(indexByRMHosts "${host}")
+ if [ -n "$index" ]; then
+ # Only RM needs to execute the following code
+ echo "Starting resourcemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-resourcemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/start-resourcemanager.sh"
+ fi
+ fi
+
+ # Start nodemanager
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ echo "Starting nodemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-nodemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/start-nodemanager.sh"
+ fi
+ fi
+
+ # Start timeline
+ if [ "x$YARN_TIMELINE_HOST" = "x$host" ]; then
+ echo "Starting timelineserver..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-timelineserver.sh"
+ su - yarn -c "${HADOOP_HOME}/sbin/start-timelinereader.sh"
+ else
+ ${HADOOP_HOME}/sbin/start-timelineserver.sh
+ ${HADOOP_HOME}/sbin/start-timelinereader.sh
+ fi
+ fi
+
+ # Start jobhistory
+ if [ "x$YARN_JOB_HISTORY_HOST" = "x$host" ]; then
+ echo "Starting mapreduce job history..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-mr-jobhistory.sh"
+ else
+ ${HADOOP_HOME}/sbin/start-mr-jobhistory.sh
+ fi
+ fi
+
+ # Start registrydns
+ if [ "x$YARN_REGISTRY_DNS_HOST" = "x$host" ]; then
+ echo "Starting registry dns..."
+ sudo ${HADOOP_HOME}/sbin/start-registrydns.sh
+ fi
+}
+
+## @description stop yarn
+## @audience public
+## @stability stable
+function stop_yarn()
+{
+ current_user=$(whoami)
+ host=$(hostname)
+ # Stop RM if the host is in YARN_RESOURCE_MANAGER_HOSTS
+ index=$(indexByRMHosts "${host}")
+ if [ -n "$index" ]; then
+ # Only RM needs to execute the following code
+ if [ ${current_user} != "yarn" ]; then
+ echo "Stopping resourcemanager..."
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-resourcemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/stop-resourcemanager.sh"
+ fi
+ fi
+
+ # Stop nodemanager
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ echo "Stopping nodemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-nodemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/stop-nodemanager.sh"
+ fi
+ fi
+
+ # Stop timeline
+ if [ "x$YARN_TIMELINE_HOST" = "x$host" ]; then
+ echo "Stopping timelineserver..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-timelineserver.sh"
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-timelinereader.sh"
+ else
+ ${HADOOP_HOME}/sbin/stop-timelineserver.sh
+ ${HADOOP_HOME}/sbin/stop-timelinereader.sh
+ fi
+ fi
+
+ # Stop jobhistory
+ if [ "x$YARN_JOB_HISTORY_HOST" = "x$host" ]; then
+ echo "Stopping mapreduce job history..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-mr-jobhistory.sh"
+ else
+ ${HADOOP_HOME}/sbin/stop-mr-jobhistory.sh
+ fi
+ fi
+
+ # Stop registrydns
+ if [ "x$YARN_REGISTRY_DNS_HOST" = "x$host" ]; then
+ echo "Stopping registry dns..."
+ sudo ${HADOOP_HOME}/sbin/stop-registrydns.sh
+ fi
+}
+
diff --git a/dev-support/submarine-installer/scripts/yarn_insecure.sh b/dev-support/submarine-installer/scripts/yarn_insecure.sh
new file mode 100644
index 0000000000000000000000000000000000000000..8e45710dc795075a3b1f572072600e5a32dd6bbd
--- /dev/null
+++ b/dev-support/submarine-installer/scripts/yarn_insecure.sh
@@ -0,0 +1,626 @@
+#!/usr/bin/env bash
+# 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.
+
+## @description install yarn
+## @audience public
+## @stability stable
+function install_yarn_insecure()
+{
+ # change the soft link of etc
+ rm -f ${PACKAGE_DIR}/hadoop/yarn/etc
+ ln -s ${PACKAGE_DIR}/hadoop/yarn/etc_insecure ${PACKAGE_DIR}/hadoop/yarn/etc
+
+ initialize_temp_insecure
+
+ host=$(hostname)
+ index=$(indexByRMHosts "${host}")
+ #if [[ -n "$index" || "x$YARN_TIMELINE_HOST" != "x$host" ]]; then
+ # kinit -kt ${HADOOP_KEYTAB_LOCATION} ${HADOOP_PRINCIPAL}
+ #fi
+
+ install_java_tarball
+ if [[ $? = 1 ]]; then
+ return 1
+ fi
+ install_yarn_tarball_insecure
+ if [[ $? = 1 ]]; then
+ return 1
+ fi
+ install_yarn_sbin_insecure
+ install_yarn_rm_nm_insecure
+ install_yarn_service_insecure
+ install_registry_dns_insecure
+ install_timeline_server_insecure
+ install_job_history_insecure
+ install_mapred_insecure
+ install_spark_shuffle_insecure
+ install_lzo_native_insecure
+
+ # copy file
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/hdfs-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/capacity-scheduler.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/resource-types.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/log4j.properties" "${HADOOP_HOME}/etc/hadoop/"
+ chown "${HADOOP_SETUP_USER}":yarn "${HADOOP_HOME}"/etc/hadoop/*
+}
+
+## @description Initialize tmp dir for installation.
+## @audience public
+## @stability stable
+function initialize_temp_insecure()
+{
+ mkdir -p "${INSTALL_TEMP_DIR}/hadoop"
+ \cp -rf "${PACKAGE_DIR}/hadoop/yarn" "${INSTALL_TEMP_DIR}/hadoop/"
+ isGpuEnabled=$(nvidia-smi)
+ if [[ -n "$isGpuEnabled" ]]; then
+ python ${SCRIPTS_DIR}/xmlcombine.py ${PACKAGE_DIR}/hadoop/yarn/etc/hadoop/yarn-site.xml ${PACKAGE_DIR}/hadoop/yarn/etc/hadoop/gpu/yarn-site-gpu.xml > "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ fi
+ chown -R ${HADOOP_SETUP_USER} "${INSTALL_TEMP_DIR}/hadoop"
+}
+
+## @description uninstall yarn
+## @audience public
+## @stability stable
+function uninstall_yarn()
+{
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ executor_conf_dir=$(dirname "${executor_dir}")/etc/hadoop
+
+ rm -rf "${YARN_CONTAINER_EXECUTOR_PATH}"
+ rm -rf "${executor_conf_dir}"
+ rm -rf "${HADOOP_HOME}"
+}
+
+## @description install yarn container executor
+## @audience public
+## @stability stable
+function install_yarn_container_executor_insecure()
+{
+ echo "install yarn container executor file ..."
+
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ if [ ! -d "${executor_dir}" ]; then
+ mkdir -p "${executor_dir}"
+ fi
+ if [ -f "${YARN_CONTAINER_EXECUTOR_PATH}" ]; then
+ if [ -f "${HADOOP_HOME}/bin/container-executor" ]; then
+ rm ${YARN_CONTAINER_EXECUTOR_PATH}
+ fi
+ fi
+
+ if [ -f "${HADOOP_HOME}/bin/container-executor" ]; then
+ cp -f "${HADOOP_HOME}/bin/container-executor" "${YARN_CONTAINER_EXECUTOR_PATH}"
+ rm "${HADOOP_HOME}/bin/container-executor"
+ fi
+
+ sudo chmod 6755 "${executor_dir}"
+ sudo chown :yarn "${YARN_CONTAINER_EXECUTOR_PATH}"
+ sudo chmod 6050 "${YARN_CONTAINER_EXECUTOR_PATH}"
+}
+
+## @description Deploy hadoop yarn tar ball
+## @audience public
+## @stability stable
+function install_yarn_tarball_insecure()
+{
+ tag=`date '+%Y%m%d%H%M%S'`
+ if [ -f "${PACKAGE_DIR}/hadoop/${HADOOP_TARBALL}" ]; then
+ tar -zxvf "${PACKAGE_DIR}/hadoop/${HADOOP_TARBALL}" -C "${PACKAGE_DIR}/hadoop/"
+ mv "${PACKAGE_DIR}/hadoop/${HADOOP_VERSION}" "/home/${HADOOP_SETUP_USER}/${HADOOP_VERSION}-${tag}"
+ chown -R ${HADOOP_SETUP_USER} "/home/hadoop/${HADOOP_VERSION}-${tag}"
+ if [[ -d "${HADOOP_HOME}" ]] || [[ -L "${HADOOP_HOME}" ]]; then
+ rm -rf ${HADOOP_HOME}
+ fi
+ ln -s "/home/hadoop/${HADOOP_VERSION}-${tag}" "${HADOOP_HOME}"
+ chown ${HADOOP_SETUP_USER} "${HADOOP_HOME}"
+ else
+ echo "ERROR: Please put ${HADOOP_TARBALL} in the path of ${PACKAGE_DIR}/hadoop/ firstly."
+ return 1
+ fi
+}
+
+## @description Deploy java tar ball
+## @audience public
+## @stability stable
+function install_java_tarball()
+{
+ if [[ -d "${JAVA_HOME}" ]] || [[ -L "${JAVA_HOME}" ]]; then
+ echo "JAVA_HOME already exists. There is no need to install java."
+ else
+ if [[ -f "${PACKAGE_DIR}/java/${JAVA_TARBALL}" ]]; then
+ tar -zxvf "${PACKAGE_DIR}/java/${JAVA_TARBALL}" -C "${PACKAGE_DIR}/java/"
+ mv "${PACKAGE_DIR}/java/${JAVA_VERSION}" "/home/${HADOOP_SETUP_USER}/${JAVA_VERSION}"
+ chown -R ${HADOOP_SETUP_USER} "/home/hadoop/${JAVA_VERSION}"
+ ln -s "/home/hadoop/${JAVA_VERSION}" "${JAVA_HOME}"
+ else
+ echo "Error: Failed to install java, please put java tarball in the path of
+ ${PACKAGE_DIR}/java/${JAVA_TARBALL}"
+ return 1
+ fi
+ fi
+}
+
+## @description install yarn resource & node manager
+## @audience public
+## @stability stable
+function install_yarn_rm_nm_insecure()
+{
+ echo "install yarn config file ..."
+ host=$(hostname)
+
+ find="/"
+ replace="\\/"
+ escape_yarn_nodemanager_local_dirs=${YARN_NODEMANAGER_LOCAL_DIRS//$find/$replace}
+ escape_yarn_nodemanager_log_dirs=${YARN_NODEMANAGER_LOG_DIRS//$find/$replace}
+ escape_yarn_hierarchy=${YARN_HIERARCHY//$find/$replace}
+ escape_yarn_nodemanager_nodes_exclude_path=${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH//$find/$replace}
+ escape_yarn_nodemanager_recovery_dir=${YARN_NODEMANAGER_RECOVERY_DIR//$find/$replace}
+ escape_fs_defaults=${FS_DEFAULTFS//$find/$replace}
+
+ # container-executor.cfg`
+ sed -i "s/YARN_NODEMANAGER_LOCAL_DIRS_REPLACE/${escape_yarn_nodemanager_local_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/YARN_NODEMANAGER_LOG_DIRS_REPLACE/${escape_yarn_nodemanager_log_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/DOCKER_REGISTRY_REPLACE/${DOCKER_REGISTRY}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/CALICO_NETWORK_NAME_REPLACE/${CALICO_NETWORK_NAME}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+ sed -i "s/YARN_HIERARCHY_REPLACE/${escape_yarn_hierarchy}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+
+ # enable cgroup for yarn
+ . "${PACKAGE_DIR}/submarine/submarine.sh"
+
+ # Delete the ASF license comment in the container-executor.cfg file, otherwise it will cause a cfg format error.
+ sed -i '1,16d' "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg"
+
+ executor_dir=$(dirname "${YARN_CONTAINER_EXECUTOR_PATH}")
+ executor_conf_dir=$(dirname "${executor_dir}")/etc/hadoop
+ if [ ! -d "${executor_conf_dir}" ]; then
+ sudo mkdir -p "${executor_conf_dir}"
+ fi
+
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/container-executor.cfg" "${executor_conf_dir}"
+
+ # yarn-site.xml
+ sed -i "s/YARN_RESOURCE_MANAGER_HOSTS1_REPLACE/${YARN_RESOURCE_MANAGER_HOSTS[0]}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_RESOURCE_MANAGER_HOSTS2_REPLACE/${YARN_RESOURCE_MANAGER_HOSTS[1]}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/LOCAL_CLUSTER_ID_REPLACE/${LOCAL_CLUSTER_ID}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_NODEMANAGER_LOCAL_DIRS_REPLACE/${escape_yarn_nodemanager_local_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_NODEMANAGER_LOG_DIRS_REPLACE/${escape_yarn_nodemanager_log_dirs}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ # Make nodemanager local dirs if the host is not in YARN_NODE_MANAGER_EXCLUDE_HOSTS
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ arr=(${YARN_NODEMANAGER_LOCAL_DIRS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ mkdir -p "${arr[$index]}"
+ (( index++ ))
+ done
+
+ arr=(${YARN_NODEMANAGER_LOG_DIRS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ mkdir -p "${arr[$index]}"
+ (( index++ ))
+ done
+
+ arr=(${YARN_NODEMANAGER_LOCAL_HOME_PATHS//,/ })
+ index=0
+ while [ "$index" -lt "${#arr[@]}" ]; do
+ chown -R yarn "${arr[$index]}"
+ (( index++ ))
+ done
+ fi
+
+ sed -i "s/YARN_ZK_ADDRESS_REPLACE/${YARN_ZK_ADDRESS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/CALICO_NETWORK_NAME_REPLACE/${CALICO_NETWORK_NAME}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+
+ sed -i "s/YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH_REPLACE/${escape_yarn_nodemanager_nodes_exclude_path}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ node_exclude_dir=$(dirname "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}")
+ if [[ ! -d "${node_exclude_dir}" ]]; then
+ mkdir -p "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ fi
+ if [[ ! -f "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}" ]]; then
+ touch "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ chmod 777 "${YARN_RESOURCEMANAGER_NODES_EXCLUDE_PATH}"
+ fi
+
+ sed -i "s/YARN_NODEMANAGER_RECOVERY_DIR_REPLACE/${escape_yarn_nodemanager_recovery_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ mkdir -p "${YARN_NODEMANAGER_RECOVERY_DIR}"
+ chmod 777 "${YARN_NODEMANAGER_RECOVERY_DIR}"
+
+ # core-site.xml
+ sed -i "s/YARN_ZK_ADDRESS_REPLACE/${YARN_ZK_ADDRESS}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+ sed -i "s/FS_DEFAULTFS_REPLACE/${escape_fs_defaults}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+
+ # WARN: ${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE} Can not be empty!
+ echo 'hello submarine' > "${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE}"
+ escape_hadoop_http_authentication_signature_secret_file=${HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE//$find/$replace}
+ sed -i "s/HADOOP_HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_REPLACE/${escape_hadoop_http_authentication_signature_secret_file}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml"
+
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/core-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+ cp -f "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/hdfs-site.xml" "${HADOOP_HOME}/etc/hadoop/"
+
+ install_yarn_container_executor_insecure
+}
+
+function install_spark_shuffle_insecure() {
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/spark* "${HADOOP_HOME}/share/hadoop/yarn/lib/"
+}
+
+function install_lzo_native_insecure() {
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/native/libgpl* "${HADOOP_HOME}/lib/native/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/yarn/lib/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/hdfs/lib/"
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/common/lib/"
+ if [ ! -d "${HADOOP_HOME}/share/hadoop/mapreduce/lib/" ]; then
+ mkdir -p "${HADOOP_HOME}/share/hadoop/mapreduce/lib/"
+ fi
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/lib/hadoop-lzo* "${HADOOP_HOME}/share/hadoop/mapreduce/lib/"
+}
+
+function install_mapred_insecure() {
+ find="/"
+ replace="\\/"
+ escape_yarn_app_mapreduce_am_staging_dir=${YARN_APP_MAPREDUCE_AM_STAGING_DIR//$find/$replace}
+ escape_fs_defaults=${FS_DEFAULTFS//$find/$replace}
+
+ sed -i "s/FS_DEFAULTFS_REPLACE/${escape_fs_defaults}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+ sed -i "s/YARN_APP_MAPREDUCE_AM_STAGING_DIR_REPLACE/${escape_yarn_app_mapreduce_am_staging_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+ host=$(hostname)
+ index=$(indexByRMHosts "${host}")
+ if [[ -n "$index" ]]; then
+ # Only RM needs to execute the following code
+ pathExists=$(pathExitsOnHDFS "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}")
+ if [[ -z "${pathExists}" ]]; then
+ echo "Create hdfs path ${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -mkdir -p "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -chown yarn:hadoop "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ "${HADOOP_HOME}/bin/hadoop" dfs -chmod 1777 "${YARN_APP_MAPREDUCE_AM_STAGING_DIR}"
+ fi
+ fi
+}
+
+function install_yarn_sbin_insecure() {
+ find="/"
+ replace="\\/"
+ escape_yarn_gc_log_dir=${YARN_GC_LOG_DIR//$find/$replace}
+ escape_java_home=${JAVA_HOME//$find/$replace}
+ escape_hadoop_home=${HADOOP_HOME//$find/$replace}
+ escape_yarn_pid_dir=${YARN_PID_DIR//$find/$replace}
+ escape_yarn_log_dir=${YARN_LOG_DIR//$find/$replace}
+ cp -R ${PACKAGE_DIR}/hadoop/yarn/sbin/* "${HADOOP_HOME}/sbin/"
+ chown "${HADOOP_SETUP_USER}":yarn "${HADOOP_HOME}"/sbin/*
+
+ if [ ! -d "$YARN_GC_LOG_DIR" ]; then
+ mkdir -p "$YARN_GC_LOG_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_GC_LOG_DIR}"
+ chmod 775 "${YARN_GC_LOG_DIR}"
+ fi
+
+ if [ ! -d "$YARN_LOG_DIR" ]; then
+ mkdir -p "$YARN_LOG_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_LOG_DIR}"
+ chmod 775 "${YARN_LOG_DIR}"
+ fi
+
+ if [ ! -d "$YARN_PID_DIR" ]; then
+ mkdir -p "$YARN_PID_DIR"
+ chown "${HADOOP_SETUP_USER}":yarn "${YARN_PID_DIR}"
+ chmod 775 "${YARN_PID_DIR}"
+ fi
+
+ sed -i "s/YARN_LOG_DIR_REPLACE/${escape_yarn_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/YARN_PID_DIR_REPLACE/${escape_yarn_pid_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/JAVA_HOME_REPLACE/${escape_java_home}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/HADOOP_HOME_REPLACE/${escape_hadoop_home}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/hadoop-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/yarn-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+ sed -i "s/GC_LOG_DIR_REPLACE/${escape_yarn_gc_log_dir}/g" "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/mapred-env.sh"
+ cp -R "${INSTALL_TEMP_DIR}/hadoop/yarn/etc/hadoop/mapred-env.sh" "${HADOOP_HOME}/etc/hadoop/"
+
+cat<
+hadoop.proxyuser.yarn.hosts
+*
+
+
+hadoop.proxyuser.yarn.groups
+*
+
+-----------------------------------------------------------------
+HELPINFO
+}
+
+function install_registry_dns_insecure() {
+ sed -i "s/YARN_REGISTRY_DNS_HOST_REPLACE/${YARN_REGISTRY_DNS_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_REGISTRY_DNS_HOST_PORT_REPLACE/${YARN_REGISTRY_DNS_HOST_PORT}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+}
+
+function install_job_history_insecure() {
+ sed -i "s/YARN_JOB_HISTORY_HOST_REPLACE/${YARN_JOB_HISTORY_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/mapred-site.xml"
+}
+
+## @description install yarn timeline server
+## @audience public
+## @stability stable
+## http://hadoop.apache.org/docs/r3.1.0/hadoop-yarn/hadoop-yarn-site/TimelineServer.html
+function install_timeline_server_insecure()
+{
+ find="/"
+ replace="\\/"
+ escape_aggregated_log_dir=${YARN_AGGREGATED_LOG_DIR//$find/$replace}
+ escape_yarn_timeline_service_hbase_configuration_file=${YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE//$find/$replace}
+ escape_yarn_timeline_fs_store_dir=${YARN_TIMELINE_FS_STORE_DIR//$find/$replace}
+ # timeline v1.5
+ escape_yarn_timeline_service_leveldb_state_store_path=${YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH//$find/$replace}
+
+ # set leveldb configuration
+ sed -i "s/YARN_AGGREGATED_LOG_DIR_REPLACE/${escape_aggregated_log_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_SERVICE_HBASE_CONFIGURATION_FILE_REPLACE/${escape_yarn_timeline_service_hbase_configuration_file}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ # timeline v1.5
+ sed -i "s/YARN_TIMELINE_HOST_REPLACE/${YARN_TIMELINE_HOST}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_SERVICE_LEVELDB_STATE_STORE_PATH_REPLACE/${escape_yarn_timeline_service_leveldb_state_store_path}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+ sed -i "s/YARN_TIMELINE_FS_STORE_DIR_REPLACE/${escape_yarn_timeline_fs_store_dir}/g" "$INSTALL_TEMP_DIR/hadoop/yarn/etc/hadoop/yarn-site.xml"
+
+ host=$(hostname)
+ if [ "x$YARN_TIMELINE_HOST" != "x$host" ]; then
+ return 0
+ fi
+
+ echo -n "Do you want to create hdfs directories for timelineserver[Y/N]?"
+ read -r answer
+ echo "$answer"
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Stop creating hdfs directories for timelineserver"
+ return 0
+ fi
+
+ echo "install yarn timeline server V1.5 ..."
+
+cat< grant 'yarn', 'RWC'
+> grant 'HTTP', 'R'
+HELPINFO
+ echo -n "Have you done the above operation[Y/N]?"
+ read -r answer
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Stop installing the timeline server V2"
+ return 0
+ fi
+
+ pathExists=$(pathExitsOnHDFS "/hbase")
+ if [[ -z "${pathExists}" ]]; then
+ "${HADOOP_HOME}/bin/hadoop" fs -mkdir -p "/hbase"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod -R 755 "/hbase"
+ fi
+
+ pathExists=$(pathExitsOnHDFS "/hbase/coprocessor")
+ if [[ -z "${pathExists}" ]]; then
+ "${HADOOP_HOME}/bin/hadoop" fs -mkdir -p "/hbase/coprocessor"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod -R 755 "/hbase/coprocessor"
+ fi
+
+ "${HADOOP_HOME}/bin/hadoop" fs -put "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-coprocessor-3.*.jar "/hbase/coprocessor/hadoop-yarn-server-timelineservice.jar"
+ "${HADOOP_HOME}/bin/hadoop" fs -chmod 755 "/hbase/coprocessor/hadoop-yarn-server-timelineservice.jar"
+
+cat</lib path:
+HELPINFO
+
+ if [[ -n "${HBASE_HOME}" ]]; then
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-common-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-hbase-client-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ cp "${HADOOP_HOME}"/share/hadoop/yarn/timelineservice/hadoop-yarn-server-timelineservice-3.*-SNAPSHOT.jar "${HBASE_HOME}/lib"
+ fi
+
+cat< path, Execute the following command to create a schema
+> bin/hbase org.apache.hadoop.yarn.server.timelineservice.storage.TimelineSchemaCreator -create
+HELPINFO
+ echo -n "Have you done the above operation[Y/N]?"
+ read -r answer
+ if [[ "$answer" = "y" || "$answer" = "Y" ]]; then
+ echo "Continue installing ..."
+ else
+ echo "Please initialize hbase timeline schema before you start timelineserver"
+ fi
+}
+
+## @description start yarn
+## @audience public
+## @stability stable
+function start_yarn()
+{
+ current_user=$(whoami)
+ host=$(hostname)
+
+ # Start RM if the host is in YARN_RESOURCE_MANAGER_HOSTS
+ index=$(indexByRMHosts "${host}")
+ if [ -n "$index" ]; then
+ # Only RM needs to execute the following code
+ echo "Starting resourcemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-resourcemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/start-resourcemanager.sh"
+ fi
+ fi
+
+ # Start nodemanager
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ echo "Starting nodemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-nodemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/start-nodemanager.sh"
+ fi
+ fi
+
+ # Start timeline
+ if [ "x$YARN_TIMELINE_HOST" = "x$host" ]; then
+ echo "Starting timelineserver..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-timelineserver.sh"
+ su - yarn -c "${HADOOP_HOME}/sbin/start-timelinereader.sh"
+ else
+ ${HADOOP_HOME}/sbin/start-timelineserver.sh
+ ${HADOOP_HOME}/sbin/start-timelinereader.sh
+ fi
+ fi
+
+ # Start jobhistory
+ if [ "x$YARN_JOB_HISTORY_HOST" = "x$host" ]; then
+ echo "Starting mapreduce job history..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/start-mr-jobhistory.sh"
+ else
+ ${HADOOP_HOME}/sbin/start-mr-jobhistory.sh
+ fi
+ fi
+
+ # Start registrydns
+ if [ "x$YARN_REGISTRY_DNS_HOST" = "x$host" ]; then
+ echo "Starting registry dns..."
+ sudo ${HADOOP_HOME}/sbin/start-registrydns.sh
+ fi
+}
+
+## @description stop yarn
+## @audience public
+## @stability stable
+function stop_yarn()
+{
+ current_user=$(whoami)
+ host=$(hostname)
+ # Stop RM if the host is in YARN_RESOURCE_MANAGER_HOSTS
+ index=$(indexByRMHosts "${host}")
+ if [ -n "$index" ]; then
+ # Only RM needs to execute the following code
+ if [ ${current_user} != "yarn" ]; then
+ echo "Stopping resourcemanager..."
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-resourcemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/stop-resourcemanager.sh"
+ fi
+ fi
+
+ # Stop nodemanager
+ index=$(indexOfNMExcludeHosts "${host}")
+ if [ -z "$index" ]; then
+ echo "Stopping nodemanager..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-nodemanager.sh"
+ else
+ "${HADOOP_HOME}/sbin/stop-nodemanager.sh"
+ fi
+ fi
+
+ # Stop timeline
+ if [ "x$YARN_TIMELINE_HOST" = "x$host" ]; then
+ echo "Stopping timelineserver..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-timelineserver.sh"
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-timelinereader.sh"
+ else
+ ${HADOOP_HOME}/sbin/stop-timelineserver.sh
+ ${HADOOP_HOME}/sbin/stop-timelinereader.sh
+ fi
+ fi
+
+ # Stop jobhistory
+ if [ "x$YARN_JOB_HISTORY_HOST" = "x$host" ]; then
+ echo "Stopping mapreduce job history..."
+ if [ ${current_user} != "yarn" ]; then
+ su - yarn -c "${HADOOP_HOME}/sbin/stop-mr-jobhistory.sh"
+ else
+ ${HADOOP_HOME}/sbin/stop-mr-jobhistory.sh
+ fi
+ fi
+
+ # Stop registrydns
+ if [ "x$YARN_REGISTRY_DNS_HOST" = "x$host" ]; then
+ echo "Stopping registry dns..."
+ sudo ${HADOOP_HOME}/sbin/stop-registrydns.sh
+ fi
+}
+
diff --git a/dev-support/travis/install_external_dependencies.sh b/dev-support/travis/install_external_dependencies.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c73f28b780b92c587c537cc23e524ea207bdf368
--- /dev/null
+++ b/dev-support/travis/install_external_dependencies.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+# 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.
+#
+
+# Script for installing R / Python dependencies for Travis CI
+set -exvuo pipefail
+touch ~/.environ
+
+# Install Python dependencies for Python specific tests
+if [[ -n "${PYTHON:-}" ]] ; then
+ wget https://repo.continuum.io/miniconda/Miniconda${PYTHON}-4.5.4-Linux-x86_64.sh -O miniconda.sh
+ bash miniconda.sh -b -p $HOME/miniconda
+ echo "export PATH='$HOME/miniconda/bin:$PATH'" >> ~/.environ
+ source ~/.environ
+
+ hash -r
+ conda config --set always_yes yes --set changeps1 no
+ conda update -q conda
+ conda info -a
+ conda config --add channels conda-forge
+
+ conda install numpy=1.13.3 pandas=0.21.1 matplotlib=2.1.1 pandasql=0.7.3 ipython=5.4.1 jupyter_client=5.1.0 ipykernel=4.7.0 bokeh=0.12.10
+ pip install scipy==1.5.2 ggplot==0.11.5 grpcio==1.8.2 bkzep==0.4.0
+
+ if [[ -n "${TENSORFLOW:-}" ]] ; then
+ check_results=`conda search -c conda-forge tensorflow`
+ echo "search tensorflow = $check_results"
+
+ pip install tensorflow=="${TENSORFLOW}"
+ fi
+fi
diff --git a/dev-support/travis/tf-operator/crd_v1.yaml b/dev-support/travis/tf-operator/crd_v1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..546e66ac0b3e9648fb5ea79611075ac35ec8a470
--- /dev/null
+++ b/dev-support/travis/tf-operator/crd_v1.yaml
@@ -0,0 +1,42 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: tfjobs.kubeflow.org
+spec:
+ group: kubeflow.org
+ scope: Namespaced
+ names:
+ kind: TFJob
+ singular: tfjob
+ plural: tfjobs
+ versions:
+ - name: v1
+ served: true
+ storage: true
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ properties:
+ spec:
+ properties:
+ tfReplicaSpecs:
+ properties:
+ # The validation works when the configuration contains
+ # `Worker`, `PS` or `Chief`. Otherwise it will not be validated.
+ Worker:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ PS:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ Chief:
+ properties:
+ replicas:
+ type: integer
+ minimum: 1
+ maximum: 1
\ No newline at end of file
diff --git a/dev-support/travis/tf-operator/tfevent-volume/tfevent-pv.yaml b/dev-support/travis/tf-operator/tfevent-volume/tfevent-pv.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a450c6a49298bc8c8ff39eea0be71dc272e3f0c0
--- /dev/null
+++ b/dev-support/travis/tf-operator/tfevent-volume/tfevent-pv.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: tfevent-volume
+ labels:
+ type: local
+ app: tfjob
+spec:
+ capacity:
+ storage: 10Gi
+ storageClassName: standard
+ accessModes:
+ - ReadWriteMany
+ hostPath:
+ path: /tmp/data
diff --git a/dev-support/travis/tf-operator/tfevent-volume/tfevent-pvc.yaml b/dev-support/travis/tf-operator/tfevent-volume/tfevent-pvc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..81c2ca944fadfe10bdb0883fc6aedd86dff4ba7d
--- /dev/null
+++ b/dev-support/travis/tf-operator/tfevent-volume/tfevent-pvc.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: tfevent-volume
+ namespace: submarine
+ labels:
+ type: local
+ app: tfjob
+spec:
+ accessModes:
+ - ReadWriteMany
+ resources:
+ requests:
+ storage: 10Gi
diff --git a/docs/assets/128-black-white.png b/docs/assets/128-black-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..510a75e2c42c601021731ec6e43acc537c202bc6
Binary files /dev/null and b/docs/assets/128-black-white.png differ
diff --git a/docs/assets/128-black.png b/docs/assets/128-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..f20d18565796c743ec8b86af6f4c894ad04b495f
Binary files /dev/null and b/docs/assets/128-black.png differ
diff --git a/docs/assets/128-white.png b/docs/assets/128-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..412d440c9b450277d38d0354c9943b7e5dfa4e68
Binary files /dev/null and b/docs/assets/128-white.png differ
diff --git a/docs/assets/128.png b/docs/assets/128.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b1af38cd28be5d5f39cb9548b494d7065df37f6
Binary files /dev/null and b/docs/assets/128.png differ
diff --git a/docs/assets/256-black-white.png b/docs/assets/256-black-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..315438bc14e272ab84e38055290df535d8517379
Binary files /dev/null and b/docs/assets/256-black-white.png differ
diff --git a/docs/assets/256-black.png b/docs/assets/256-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..4813aea040986f7fb7e6b9a3e501e96e3f83764f
Binary files /dev/null and b/docs/assets/256-black.png differ
diff --git a/docs/assets/256-white-backup.png b/docs/assets/256-white-backup.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dad26e17c87251659a9cd334fff892b77661cb4
Binary files /dev/null and b/docs/assets/256-white-backup.png differ
diff --git a/docs/assets/256-white.png b/docs/assets/256-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a10402a4a8ad2538a61db0f844135a994056506
Binary files /dev/null and b/docs/assets/256-white.png differ
diff --git a/docs/assets/256.png b/docs/assets/256.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff55ec2c17bbb9de800d5fd2cb9944ed0df6b3d0
Binary files /dev/null and b/docs/assets/256.png differ
diff --git a/docs/assets/32-black-white.png b/docs/assets/32-black-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..a15b54a768519071224385b0d922ae452c1da6a7
Binary files /dev/null and b/docs/assets/32-black-white.png differ
diff --git a/docs/assets/32-black.png b/docs/assets/32-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..732d48423b0a4f61421fa30b078121a134c94588
Binary files /dev/null and b/docs/assets/32-black.png differ
diff --git a/docs/assets/32-white.png b/docs/assets/32-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab0a2559cf46293e6479dc850641746d9e0b7f9e
Binary files /dev/null and b/docs/assets/32-white.png differ
diff --git a/docs/assets/32.png b/docs/assets/32.png
new file mode 100644
index 0000000000000000000000000000000000000000..5acd270033df0976bf072bfebb091c86efc4a425
Binary files /dev/null and b/docs/assets/32.png differ
diff --git a/docs/assets/64-black-white.png b/docs/assets/64-black-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..336c9192de201a6c663919c4ea88d3c1b9230689
Binary files /dev/null and b/docs/assets/64-black-white.png differ
diff --git a/docs/assets/64-black.png b/docs/assets/64-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..e311f59e13164630b758e616e9af30c8da3abdb7
Binary files /dev/null and b/docs/assets/64-black.png differ
diff --git a/docs/assets/64-white.png b/docs/assets/64-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..87790723cf5722b84084999aee665bdca254194b
Binary files /dev/null and b/docs/assets/64-white.png differ
diff --git a/docs/assets/64.png b/docs/assets/64.png
new file mode 100644
index 0000000000000000000000000000000000000000..d53b6014a9c1bd8496d5efea585312a44cff6f14
Binary files /dev/null and b/docs/assets/64.png differ
diff --git a/docs/assets/LOGO-black.svg b/docs/assets/LOGO-black.svg
new file mode 100644
index 0000000000000000000000000000000000000000..fd443318ecc7f98b7268126e5d13dc8685ec1635
--- /dev/null
+++ b/docs/assets/LOGO-black.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/docs/assets/LOGO-blue.svg b/docs/assets/LOGO-blue.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2558ffa0e18493161b42f2761c90359798eae341
--- /dev/null
+++ b/docs/assets/LOGO-blue.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/docs/assets/LOGO-white.svg b/docs/assets/LOGO-white.svg
new file mode 100644
index 0000000000000000000000000000000000000000..76a614ca084970a83601d74ec90ab191a8f268b3
--- /dev/null
+++ b/docs/assets/LOGO-white.svg
@@ -0,0 +1,80 @@
+
+
+
diff --git a/docs/assets/Run-Debug-Configuration.png b/docs/assets/Run-Debug-Configuration.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bff9c255bc50dcfe9537c7c13ee2c952eab4a2e
Binary files /dev/null and b/docs/assets/Run-Debug-Configuration.png differ
diff --git a/docs/assets/apache_incubator.png b/docs/assets/apache_incubator.png
new file mode 100644
index 0000000000000000000000000000000000000000..987c79e3ad3130904ea4ea5e3062d59d2bae805b
Binary files /dev/null and b/docs/assets/apache_incubator.png differ
diff --git a/docs/assets/architecture.png b/docs/assets/architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..1949499e37109abd47269d19cd3d19b0686911c8
Binary files /dev/null and b/docs/assets/architecture.png differ
diff --git a/docs/assets/asf_feather.png b/docs/assets/asf_feather.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0ebf11a6478c337f6897cd2ab8a221bd0fccd3f
Binary files /dev/null and b/docs/assets/asf_feather.png differ
diff --git a/docs/assets/color_logo_with_text.png b/docs/assets/color_logo_with_text.png
new file mode 100644
index 0000000000000000000000000000000000000000..88b28f8a1bec05d2f764ab24a1666905ef71b3c3
Binary files /dev/null and b/docs/assets/color_logo_with_text.png differ
diff --git a/docs/assets/color_logo_with_text.psd b/docs/assets/color_logo_with_text.psd
new file mode 100644
index 0000000000000000000000000000000000000000..59d176a831f225c24c84c22ddcc7ee82e8e0ee15
Binary files /dev/null and b/docs/assets/color_logo_with_text.psd differ
diff --git a/docs/assets/created-notebook.png b/docs/assets/created-notebook.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d08f3f61fdb43e3dde457a7e1a9b4dc70a43337
Binary files /dev/null and b/docs/assets/created-notebook.png differ
diff --git a/docs/assets/design/experiments.png b/docs/assets/design/experiments.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3deb321f319c02f57b80160e509980a65c47874
Binary files /dev/null and b/docs/assets/design/experiments.png differ
diff --git a/docs/assets/design/multi-dc-cloud.png b/docs/assets/design/multi-dc-cloud.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b5cfbb2eff1a82a3b6c88b2c8f6ec06679d5e88
Binary files /dev/null and b/docs/assets/design/multi-dc-cloud.png differ
diff --git a/docs/assets/job-logs-ui.png b/docs/assets/job-logs-ui.png
new file mode 100644
index 0000000000000000000000000000000000000000..18b9e17f10762f2d6e5ba2acaa5658d71efd2007
Binary files /dev/null and b/docs/assets/job-logs-ui.png differ
diff --git a/docs/assets/logo-UEDC.psd b/docs/assets/logo-UEDC.psd
new file mode 100644
index 0000000000000000000000000000000000000000..bbc938d6c54eb2f6e4c1ac8ea07c999768b934e2
Binary files /dev/null and b/docs/assets/logo-UEDC.psd differ
diff --git a/docs/assets/logo-org.psd b/docs/assets/logo-org.psd
new file mode 100644
index 0000000000000000000000000000000000000000..874edbab44fa43857665f3e2fe632311da1fecda
Binary files /dev/null and b/docs/assets/logo-org.psd differ
diff --git a/docs/assets/logo.psd b/docs/assets/logo.psd
new file mode 100644
index 0000000000000000000000000000000000000000..9124ba0a46bf27e4e967adf348345c2f64621355
Binary files /dev/null and b/docs/assets/logo.psd differ
diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4bbdf7c8115fbc5264dc1e2acfa7b15972c22159
--- /dev/null
+++ b/docs/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/multiple-tensorboard-jobs.png b/docs/assets/multiple-tensorboard-jobs.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e3db797269a56279a31a5fc5df185985301e713
Binary files /dev/null and b/docs/assets/multiple-tensorboard-jobs.png differ
diff --git a/docs/assets/notebook-form.png b/docs/assets/notebook-form.png
new file mode 100644
index 0000000000000000000000000000000000000000..04208ad7a46ea4bd10eaec0cf8200c8aa31fece9
Binary files /dev/null and b/docs/assets/notebook-form.png differ
diff --git a/docs/assets/notebook-list.png b/docs/assets/notebook-list.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a90526d4e0898feccaf041c848f487e9933dc19
Binary files /dev/null and b/docs/assets/notebook-list.png differ
diff --git a/docs/assets/submarine-installer.gif b/docs/assets/submarine-installer.gif
new file mode 100644
index 0000000000000000000000000000000000000000..56b3b690f0ad4fd4f4d21c461bee6e1714070fbf
Binary files /dev/null and b/docs/assets/submarine-installer.gif differ
diff --git a/docs/assets/tensorboard-service.png b/docs/assets/tensorboard-service.png
new file mode 100644
index 0000000000000000000000000000000000000000..3251d74531bf0668193cb8e7c48422c5a2e6d130
Binary files /dev/null and b/docs/assets/tensorboard-service.png differ
diff --git a/docs/community/HowToCommit.md b/docs/community/HowToCommit.md
new file mode 100644
index 0000000000000000000000000000000000000000..143e6bc52f730123b23aa3279611a208844131fc
--- /dev/null
+++ b/docs/community/HowToCommit.md
@@ -0,0 +1,78 @@
+
+# Guide for Apache Submarine Committers
+
+This page contains Hadoop Core-specific guidelines for committers.
+
+## New committers
+New committers are encouraged to first read Apache's generic committer documentation:
+
+* [Apache New Committer Guide](http://www.apache.org/dev/new-committers-guide.html)
+* [Apache Committer FAQ](http://www.apache.org/dev/committers.html)
+
+The first act of a new core committer is typically to add their name to the
+credits page. This requires changing the site source in
+https://github.com/apache/submarine-site/blob/master/community/member.md. Once done,
+update the Submarine website as described
+[here](https://github.com/apache/submarine-site/blob/asf-site/README.md)
+(TLDR; don't forget to regenerate the site with hugo, and commit the generated
+results, too).
+
+## Review
+Submarine committers should, as often as possible, attempt to review patches
+submitted by others. Ideally every submitted patch will get reviewed by a
+committer within a few days. If a committer reviews a patch they've not
+authored, and believe it to be of sufficient quality, then they can commit the
+patch, otherwise the patch should be cancelled with a clear explanation for why
+it was rejected.
+
+The list of submitted patches can be found in the GitHub
+[Pull Requests](https://github.com/apache/submarine/pulls) page.
+Committers should scan the list from top-to-bottom,
+looking for patches that they feel qualified to review and possibly commit.
+
+For non-trivial changes, it is best to get another committer to review & approve
+your own patches before commit.
+
+## Reject
+Patches should be rejected which do not adhere to the guidelines in
+[Contribution Guidelines](contributing.md). Committers should always be
+polite to contributors and try to instruct and encourage them to contribute
+better patches. If a committer wishes to improve an unacceptable patch, then it
+should first be rejected, and a new patch should be attached by the committer
+for review.
+
+## Commit individual patches
+Submarine uses git for source code version control. The writable repo is at -
+https://gitbox.apache.org/repos/asf/submarine.git
+
+It is strongly recommended to use the cicd script to merge the PRs.
+See the instructions at
+https://github.com/apache/submarine/tree/master/dev-support/cicd
+
+## Adding Contributors role
+There are three roles (Administrators, Committers, Contributors) in the project.
+
+* Contributors who have Contributors role can become assignee of the issues in the project.
+* Committers who have Committers role can set arbitrary roles in addition to Contributors role.
+* Committers who have Administrators role can edit or delete all comments, or even delete issues in addition to Committers role.
+
+How to set roles
+
+1. Login to ASF JIRA
+2. Go to the project page (e.g. https://issues.apache.org/jira/browse/SUBMARINE )
+3. Hit "Administration" tab
+4. Hit "Roles" tab in left side
+5. Add Administrators/Committers/Contributors role
diff --git a/docs/community/README.md b/docs/community/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..160e9ee563beb8b166ceb837993ca32a4544865c
--- /dev/null
+++ b/docs/community/README.md
@@ -0,0 +1,71 @@
+
+
+## Apache Submarine Community
+
+Welcome to the Apache Submarine Community! The main objective is to help members of the Submarine community who share similar interests to learn from and collaborate with each other.
+
+Your journey of becoming a contributor and committer starts from here: improving docs, improving code, giving talks, organizing meetups, etc.
+
+## Communicating
+
+You can reach out to the community members via any one of the following ways:
+
++ Slack Developer: [https://the-asf.slack.com/submarine-dev/](https://the-asf.slack.com/submarine-dev/)
+
++ Slack User: [https://the-asf.slack.com/submarine-user/](https://the-asf.slack.com/submarine-user/)
+
++ Zoom: [https://cloudera.zoom.us/j/880548968](https://cloudera.zoom.us/j/880548968)
+
++ Sync Up: [https://docs.google.com/document/d/16pUO3TP4SxSeLduG817GhVAjtiph9HYpRHo_JgduDvw/edit](https://docs.google.com/document/d/16pUO3TP4SxSeLduG817GhVAjtiph9HYpRHo_JgduDvw/edit)
+
+## Your First Contribution
+
+You can start by finding an existing issue with the [https://issues.apache.org/jira/projects/SUBMARINE/issues/SUBMARINE?filter=allopenissues](https://issues.apache.org/jira/projects/SUBMARINE/issues/SUBMARINE?filter=allopenissues) label. These issues are well suited for new contributors.
+
+If a PR (Pull Request) submitted to the [Submarine Github](https://github.com/apache/submarine) projects by you is approved and merged, then you become a Submarine Contributor.
+
+If you want to work on a new idea of relatively small scope:
+
+1. Submit an issue describing your proposed change to the repo in question.
+
+2. The repo owners will respond to your issue promptly.
+
+3. Submit a [pull request of Submarine](https://github.com/apache/submarine) containing a tested change.
+
+Once you become a contributor of Apache Submarine, check your name here: [CONTRIBUTORS](contributors.md)
+
+Contributions are welcomed and greatly appreciated. See [CONTRIBUTING.md](contributing.md) for details on submitting patches and the contribution workflow.
+
+## How Do I Become a Committer?
+
+First of all, you need to get involved and be a Contributor.
+
+Based on your track-record as a contributor, Per Apache code, PMCs vote on committership, may invite you to be a committer (after we've called a vote). When that happens, if you accept, the following process kicks into place...
+
+Note that becoming a committer is not just about submitting some patches; it‘s also about helping out on the development and user [Slack User](https://the-asf.slack.com/submarine-user/), helping with documentation and the issues.
+
+See [Become a Committer.md](become-a-committer.md) for steps of becoming a committer and more details.
+
+## How to commit
+
+See [How to commit](HowToCommit.md) for helper doc for Submarine committers.
+
+## Communication
+
+Communication within the Submarine community abides by [Apache’s Code of Conduct](https://www.apache.org/foundation/policies/conduct.html).
+
+## License
+
+Submarine source code is under the Apache 2.0 license. See the [LICENSE](https://github.com/apache/submarine/blob/master/LICENSE) file for details.
diff --git a/docs/community/become-a-committer.md b/docs/community/become-a-committer.md
new file mode 100644
index 0000000000000000000000000000000000000000..fb61776c391ce04314722660c444b9dd4f6281c5
--- /dev/null
+++ b/docs/community/become-a-committer.md
@@ -0,0 +1,15 @@
+
+
+# Become a Committer
diff --git a/docs/community/contributing.md b/docs/community/contributing.md
new file mode 100644
index 0000000000000000000000000000000000000000..e0fbfa9464375d17313b1848d21628c2e77e15ab
--- /dev/null
+++ b/docs/community/contributing.md
@@ -0,0 +1,264 @@
+
+
+# Contribution Guidelines
+
+**Apache Hadoop Submarine** is an [Apache 2.0 License](https://github.com/apache/submarine/blob/master/LICENSE) Software.
+
+Contributing to Hadoop Submarine (Source code, Documents, Image, Website) means you agree to the Apache 2.0 License.
+
+1. Make sure your issue is not already in the [Jira issue tracker](https://issues.apache.org/jira/browse/SUBMARINE)
+2. If not, create a ticket describing the change you're proposing in the [Jira issue tracker](https://issues.apache.org/jira/browse/SUBMARINE)
+3. Setup Travis [Continuous Integration](#continuous-integration)
+4. Contribute your patch via Pull Request on our [Github Mirror](https://github.com/apache/submarine).
+
+Before you start, please read the [Code of Conduct](http://www.apache.org/foundation/policies/conduct.html) carefully, familiarize yourself with it and refer to it whenever you need it.
+
+For those of you who are not familiar with the Apache project, understanding [How it works](http://www.apache.org/foundation/how-it-works.html) would be quite helpful.
+
+## Creating a Pull Request
+When creating a Pull Request, you will automatically get the template below.
+
+Filling it thoroughly can improve the speed of the review process.
+
+ ### What is this PR for?
+ A few sentences describing the overall goals of the pull request's commits.
+ First time? Check out the contribution guidelines -
+ https://github.com/apache/submarine/tree/master/docs/community/contributing.md
+
+ ### What type of PR is it?
+ [Bug Fix | Improvement | Feature | Documentation | Hot Fix | Refactoring]
+
+ ### Todos
+ * [ ] - Task
+
+ ### What is the Jira issue?
+ * Open an issue on Jira https://issues.apache.org/jira/browse/SUBMARINE/
+ * Put link here, and add [SUBMARINE-${jira_number}] in PR title, e.g. [SUBMARINE-323]
+
+ ### How should this be tested?
+ Outline the steps to test the PR here.
+
+ ### Screenshots (if appropriate)
+
+ ### Questions:
+ * Do the licenses files require updates?
+ * Are there breaking changes for older versions?
+ * Does this need documentation?
+
+
+## Source Control Workflow
+Hadoop Submarine follows [Fork & Pull](https://github.com/sevntu-checkstyle/sevntu.checkstyle/wiki/Development-workflow-with-Git:-Fork,-Branching,-Commits,-and-Pull-Request) model.
+
+## The Review Process
+
+When a Pull Request is submitted, it is being merged or rejected by the following review process.
+
+* Anybody can be a reviewer and may comment on the change or suggest modifications.
+* Reviewer can indicate that a patch looks suitable for merging with a comment such as: "Looks good", "LGTM", "+1".
+* At least one indication of suitability (e.g. "LGTM") from a committer is required to be merged.
+* Pull request is open for 1 or 2 days for potential additional review unless it's got enough indication of suitability.
+* A committer can then initiate lazy consensus ("Merge if there is no more discussion") after which the code can be merged after a particular time (usually 24 hours) if there are no more reviews.
+* Contributors can ping reviewers (including committers) by commenting 'Ready to review' or suitable indication.
+
+
+## Setting up
+Here are some things you will need to build and test the Hadoop Submarine.
+
+### Software Configuration Management (SCM)
+
+Hadoop Submarine uses Git for its SCM system. So you'll need a git client installed on your development machine.
+
+### Integrated Development Environment (IDE)
+
+You are free to use whatever IDE you prefer, or your favorite command-line editor.
+
+### Code convention
+We are following Google Code style:
+
+* [Java style](https://google.github.io/styleguide/javaguide.html)
+* [Shell style](https://google.github.io/styleguide/shell.xml)
+
+There are some plugins to format, lint your code in IDE (use [dev-support/maven-config/checkstyle.xml](hhttps://github.com/apache/submarine/blob/master/dev-support/maven-config/checkstyle.xml) as rules)
+
+* [Checkstyle plugin for Intellij](https://plugins.jetbrains.com/plugin/1065) ([Setting Guide](http://stackoverflow.com/questions/26955766/intellij-idea-checkstyle))
+* [Checkstyle plugin for Eclipse](http://eclipse-cs.sourceforge.net/#!/) ([Setting Guide](http://eclipse-cs.sourceforge.net/#!/project-setup))
+
+
+## Getting the source code
+
+### Step 1: Fork in the cloud
+
+1. Visit https://github.com/apache/submarine
+2. On the top right of the page, click the `Fork` button (top right) to create a cloud-based fork of the repository.
+
+### Step 2: Clone fork to local storage
+
+Create your clone:
+
+> ${user} is your github user name
+
+```sh
+mkdir -p ${working_dir}
+cd ${working_dir}
+
+git clone https://github.com/${user}/submarine.git
+# or: git clone git@github.com:${user}/submarine.git
+
+cd ${working_dir}/submarine
+git remote add upstream https://github.com/apache/submarine.git
+# or: git remote add upstream git@github.com:apache/submarine.git
+
+# Never push to the upstream master.
+git remote set-url --push upstream no_push
+
+# Confirm that your remotes make sense:
+# It should look like:
+# origin git@github.com:${user}/submarine.git (fetch)
+# origin git@github.com:${user}/submarine.git (push)
+# upstream https://github.com/apache/submarine (fetch)
+# upstream no_push (push)
+git remote -v
+```
+
+### Step 3: Branch
+
+Get your local master up to date:
+
+```sh
+cd ${working_dir}/submarine
+git fetch upstream
+git checkout master
+git rebase upstream/master
+```
+
+Branch from master:
+
+```sh
+git checkout -b SUBMARINE-${jira_number}
+```
+
+### Step 4: Develop
+
+#### Edit the code
+
+You can now edit the code on the `SUBMARINE-${jira_number}` branch.
+
+#### Test
+
+Build and run all tests:
+
+### Step 5: Keep your branch in sync
+
+```sh
+# While on your SUBMARINE-${jira_number} branch.
+git fetch upstream
+git rebase upstream/master
+```
+
+Please don't use `git pull` instead of the above `fetch`/`rebase`. `git pull` does a merge, which leaves merge commits. These make the commit history messy and violate the principle that commits ought to be individually understandable and useful (see below). You can also consider changing your `.git/config` file via `git config branch.autoSetupRebase` always to change the behavior of `git pull`.
+
+### Step 6: Commit
+
+Commit your changes.
+
+```sh
+git commit
+```
+
+Likely you'll go back and edit/build/test further and then `commit --amend` in a few cycles.
+
+### Step 7: Push
+
+When the changes are ready to review (or you just want to create an offsite backup of your work), push your branch to your fork on `github.com`:
+
+```sh
+git push --set-upstream ${your_remote_name} SUBMARINE-${jira_number}
+```
+
+### Step 8: Create a pull request
+
+1. Visit your fork at `https://github.com/${user}/submarine`.
+2. Click the `Compare & Pull Request` button next to your `SUBMARINE-${jira_number}` branch.
+3. Fill in the required information in the PR template.
+
+#### Get a code review
+
+If your pull request (PR) is opened, it will be assigned to one or more reviewers. Those reviewers will do a thorough code review, looking at correctness, bugs, opportunities for improvement, documentation comments, and style.
+
+To address review comments, you should commit the changes to the same branch of the PR on your fork.
+
+#### Revert a commit
+
+In case you wish to revert a commit, follow the instructions below:
+
+> NOTE: If you have upstream write access, please refrain from using the Revert
+> button in the GitHub UI for creating the PR, because GitHub will create the
+> PR branch inside the main repository rather than inside your fork.
+
+Create a branch and synchronize it with the upstream:
+
+```sh
+# create a branch
+git checkout -b myrevert
+
+# sync the branch with upstream
+git fetch upstream
+git rebase upstream/master
+
+# SHA is the hash of the commit you wish to revert
+git revert SHA
+```
+
+This creates a new commit reverting the change. Push this new commit to your remote:
+
+```sh
+git push ${your_remote_name} myrevert
+```
+
+Create a PR based on this branch.
+
+#### Cherry pick a commit to a release branch
+
+In case you wish to cherry pick a commit to a release branch, follow the instructions below:
+
+Create a branch and synchronize it with the upstream:
+
+```sh
+# sync the branch with upstream.
+git fetch upstream
+
+# checkout the release branch.
+# ${release_branch_name} is the release branch you wish to cherry pick to.
+git checkout upstream/${release_branch_name}
+git checkout -b my-cherry-pick
+
+# cherry pick the commit to my-cherry-pick branch.
+# ${SHA} is the hash of the commit you wish to revert.
+git cherry-pick ${SHA}
+
+# push this branch to your repo, file an PR based on this branch.
+git push --set-upstream ${your_remote_name} my-cherry-pick
+```
+
+## Build
+
+[Build From Code](../development/BuildFromCode.md)
+
+## Continuous Integration
+
+Hadoop Submarine project's CI system will collect information from pull request author's Travis-ci and display status in the pull request.
+
+Each individual contributor should setup Travis-ci for the fork before making a pull-request. Go to [https://travis-ci.org/profile](https://travis-ci.org/profile) and switch on 'submarine' repository.
+
diff --git a/docs/community/contributors.md b/docs/community/contributors.md
new file mode 100644
index 0000000000000000000000000000000000000000..8cf332e66c08955d5aee6bcdf8c5bbd39c3a9e39
--- /dev/null
+++ b/docs/community/contributors.md
@@ -0,0 +1,15 @@
+
+
+# Hadoop Submarine contributors
diff --git a/docs/database/README.md b/docs/database/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..bf0e4ad297d1899f2404eb0353e8df127722d119
--- /dev/null
+++ b/docs/database/README.md
@@ -0,0 +1,163 @@
+
+
+# Submarine Database
+
+Submarine needs to use the database to store information about the `organization`, `user`, `projects`, `tasks`, `metastore` and `configuration` of the system information, So consider using mysql to store this data.
+
++ MySQL will be included in the `mini-submarine` docker image to allow users to quickly experience the `submarine workbench`.
++ In a production environment, the `submarine workbench` can be connected to the official mysql database.
+
+## Prerequisite
+
+Must:
+
+- MySQL
+- MyBatis
+
+## Run mysql on docker
+
+By using the official docker image of submarine database, only one docker command is required to run submarine database
+
+```bash
+docker run -it -p 3306:3306 -d --name submarine-database -e MYSQL_ROOT_PASSWORD=password apache/submarine:database-
+```
+## Initialize submarine database
+It will create users and tables that submarine requires
+```shell script
+sudo ./init-database
+```
+## Manual operation of the submarine database
+
+### Modify character set (Optional)
+
+If you need to store Chinese character data in mysql, you need to execute the following command to modify the mysql character set.
+
++ Set database character set
+
+ ```
+ bash > mysql -uroot -ppassword
+
+ mysql>SHOW VARIABLES LIKE 'character_set_%'; // View database character set
+ mysql>SHOW VARIABLES LIKE 'collation_%';
+
+ SET NAMES 'utf8';
+ ```
+
++ Configuration `mysqld.cnf`
+
+ ```
+ # install vim
+ apt-get update
+ apt-get install vim
+
+ vi /etc/mysql/mysql.conf.d/mysqld.cnf
+
+ [mysqld]
+ character_set_server = utf8
+
+ [mysql]
+ default-character-set = utf8
+
+ [mysql.server]
+ default-character-set = utf8
+
+ [mysqld_safe]
+ default-character-set = utf8
+
+ [client]
+ default-character-set = utf8
+ ```
+
+### Create Submarine Database
+
+
+#### Create development database
+
+Run [mysql docker container](https://hub.docker.com/_/mysql)
+
+```
+docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
+```
+
+Copy the files, submarine.sql, submarine-data.sql and metastore.sql to the mysql docker.
+
+```
+docker cp ${SUBMARINE_HOME}/docs/database/submarine.sql ${DOCKER_ID}:/
+docker cp ${SUBMARINE_HOME}/docs/database/submarine-data.sql ${DOCKER_ID}:/
+docker cp ${SUBMARINE_HOME}/docs/database/metastore.sql ${DOCKER_ID}:/
+```
+
+Development database for development environment.
+
+```
+# in mysql container
+bash > mysql -uroot -ppassword
+mysql> CREATE USER IF NOT EXISTS 'submarine'@'%' IDENTIFIED BY 'password';
+mysql> GRANT ALL PRIVILEGES ON * . * TO 'submarine'@'%';
+mysql> CREATE DATABASE IF NOT EXISTS submarine CHARACTER SET utf8 COLLATE utf8_general_ci;
+mysql> use submarine;
+mysql> source /submarine.sql;
+mysql> source /submarine-data.sql;
+mysql> CREATE USER IF NOT EXISTS 'metastore'@'%' IDENTIFIED BY 'password';
+mysql> GRANT ALL PRIVILEGES ON * . * TO 'metastore'@'%';
+mysql> CREATE DATABASE IF NOT EXISTS metastore CHARACTER SET utf8 COLLATE utf8_general_ci;
+mysql> use metastore;
+mysql> source /metastore.sql;
+mysql> quit
+```
+
+> NOTE: submarine development database name is `submarine` and user name is `submarine`, password is `password`, metastore development database name is `metastore` and user name is `metastore`, password is `password`, This is the default value in the system's `submarine-site.xml` configuration file and is not recommended for modification.
+
+
+#### Create test database
+
+Test database for program unit testing and Travis test environment.
+
+```
+# in mysql container
+bash > mysql -uroot -ppassword
+mysql> CREATE USER IF NOT EXISTS 'submarine_test'@'%' IDENTIFIED BY 'password_test';
+mysql> GRANT ALL PRIVILEGES ON * . * TO 'submarine_test'@'%';
+mysql> CREATE DATABASE IF NOT EXISTS `submarine_test` CHARACTER SET utf8 COLLATE utf8_general_ci;
+mysql> use `submarine_test`;
+mysql> source /submarine.sql;
+mysql> CREATE USER IF NOT EXISTS 'metastore_test'@'%' IDENTIFIED BY 'password_test';
+mysql> GRANT ALL PRIVILEGES ON * . * TO 'metastore_test'@'%';
+mysql> CREATE DATABASE IF NOT EXISTS `metastore_test` CHARACTER SET utf8 COLLATE utf8_general_ci;
+mysql> use `metastore_test`;
+mysql> source /metastore.sql;
+mysql> quit
+```
+
+> NOTE: submarine test database name is `submarine_test` and user name is `submarine_test`, password is `password_test`, metastore test database name is `metastore_test` and user name is `metastore_test`, password is `password_test`, Cannot be configured, values that cannot be modified.
+
+#### mysqldump
+
+```$xslt
+mysqldump -uroot -ppassword --databases submarine > submarine.sql;
+mysqldump -umetastore -ppassword metastore > metastore.sql;
+```
+
+
+## Travis
+
+1. In the submarine's Travis, the `test database`, `database name`, `username` and `password` will be automatically created based on the contents of this document.
+
+ Therefore, do not modify the database's `database name`, `username` and `password` configuration to avoid introducing some problems.
+
+2. In the mysql database in Travis, the `submarine.sql` are executed to create the submarine database table structure and test data.
+
+3. The submarine database test case written in the `workbench-server` module will also be unit tested in the mysql database in travis.
diff --git a/docs/database/init-database.sh b/docs/database/init-database.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f9bf04798e833da903852b83761bc469c5150751
--- /dev/null
+++ b/docs/database/init-database.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+#
+# 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.
+
+FWDIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$FWDIR"
+
+mysql -e "CREATE DATABASE IF NOT EXISTS submarine_test;"
+mysql -e "CREATE USER IF NOT EXISTS 'submarine_test'@'%' IDENTIFIED BY 'password_test';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'submarine_test'@'%';"
+mysql -e "use submarine_test; source ./submarine.sql; show tables;"
+
+mysql -e "CREATE DATABASE IF NOT EXISTS metastore_test;"
+mysql -e "CREATE USER IF NOT EXISTS 'metastore_test'@'%' IDENTIFIED BY 'password_test';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'metastore_test'@'%';"
+mysql -e "use metastore_test; source ./metastore.sql; show tables;"
+
+mysql -e "CREATE DATABASE IF NOT EXISTS submarine;"
+mysql -e "CREATE USER IF NOT EXISTS 'submarine'@'%' IDENTIFIED BY 'password';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'submarine'@'%';"
+mysql -e "use submarine; source ./submarine.sql; source ./submarine-data.sql; show tables;"
+
+mysql -e "CREATE DATABASE IF NOT EXISTS metastore;"
+mysql -e "CREATE USER IF NOT EXISTS 'metastore'@'%' IDENTIFIED BY 'password';"
+mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'metastore'@'%';"
+mysql -e "use metastore; source ./metastore.sql; show tables;"
diff --git a/docs/database/metastore.sql b/docs/database/metastore.sql
new file mode 100644
index 0000000000000000000000000000000000000000..041c96d9ef265f767b1e557af1e09f142dd4b80e
--- /dev/null
+++ b/docs/database/metastore.sql
@@ -0,0 +1,982 @@
+-- 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.
+
+-- fork by https://github.com/apache/hive/blob/master/metastore/scripts/
+-- upgrade/mysql/hive-schema-2.3.0.mysql.sql
+
+-- fork by https://github.com/apache/hive/blob/master/metastore/scripts/
+-- upgrade/mysql/hive-txn-schema-2.3.0.mysql.sql
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `BUCKETING_COLS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `BUCKETING_COLS` (
+ `SD_ID` bigint(20) NOT NULL,
+ `BUCKET_COL_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`SD_ID`,`INTEGER_IDX`),
+ KEY `BUCKETING_COLS_N49` (`SD_ID`),
+ CONSTRAINT `BUCKETING_COLS_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `CDS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `CDS` (
+ `CD_ID` bigint(20) NOT NULL,
+ PRIMARY KEY (`CD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `COLUMNS_V2`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `COLUMNS_V2` (
+ `CD_ID` bigint(20) NOT NULL,
+ `COMMENT` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TYPE_NAME` MEDIUMTEXT DEFAULT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`CD_ID`,`COLUMN_NAME`),
+ KEY `COLUMNS_V2_N49` (`CD_ID`),
+ CONSTRAINT `COLUMNS_V2_FK1` FOREIGN KEY (`CD_ID`) REFERENCES `CDS` (`CD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `DATABASE_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `DATABASE_PARAMS` (
+ `DB_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(180) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`DB_ID`,`PARAM_KEY`),
+ KEY `DATABASE_PARAMS_N49` (`DB_ID`),
+ CONSTRAINT `DATABASE_PARAMS_FK1` FOREIGN KEY (`DB_ID`) REFERENCES `DBS` (`DB_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `DBS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `DBS` (
+ `DB_ID` bigint(20) NOT NULL,
+ `DESC` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `DB_LOCATION_URI` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `OWNER_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `OWNER_TYPE` varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`DB_ID`),
+ UNIQUE KEY `UNIQUE_DATABASE` (`NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `DB_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `DB_PRIVS` (
+ `DB_GRANT_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `DB_ID` bigint(20) DEFAULT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `DB_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`DB_GRANT_ID`),
+ UNIQUE KEY `DBPRIVILEGEINDEX` (`DB_ID`,`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`DB_PRIV`,`GRANTOR`,`GRANTOR_TYPE`),
+ KEY `DB_PRIVS_N49` (`DB_ID`),
+ CONSTRAINT `DB_PRIVS_FK1` FOREIGN KEY (`DB_ID`) REFERENCES `DBS` (`DB_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `GLOBAL_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `GLOBAL_PRIVS` (
+ `USER_GRANT_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `USER_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`USER_GRANT_ID`),
+ UNIQUE KEY `GLOBALPRIVILEGEINDEX` (`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`USER_PRIV`,`GRANTOR`,`GRANTOR_TYPE`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `IDXS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `IDXS` (
+ `INDEX_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `DEFERRED_REBUILD` bit(1) NOT NULL,
+ `INDEX_HANDLER_CLASS` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INDEX_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INDEX_TBL_ID` bigint(20) DEFAULT NULL,
+ `LAST_ACCESS_TIME` int(11) NOT NULL,
+ `ORIG_TBL_ID` bigint(20) DEFAULT NULL,
+ `SD_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`INDEX_ID`),
+ UNIQUE KEY `UNIQUEINDEX` (`INDEX_NAME`,`ORIG_TBL_ID`),
+ KEY `IDXS_N51` (`SD_ID`),
+ KEY `IDXS_N50` (`INDEX_TBL_ID`),
+ KEY `IDXS_N49` (`ORIG_TBL_ID`),
+ CONSTRAINT `IDXS_FK1` FOREIGN KEY (`ORIG_TBL_ID`) REFERENCES `TBLS` (`TBL_ID`),
+ CONSTRAINT `IDXS_FK2` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`),
+ CONSTRAINT `IDXS_FK3` FOREIGN KEY (`INDEX_TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `INDEX_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `INDEX_PARAMS` (
+ `INDEX_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`INDEX_ID`,`PARAM_KEY`),
+ KEY `INDEX_PARAMS_N49` (`INDEX_ID`),
+ CONSTRAINT `INDEX_PARAMS_FK1` FOREIGN KEY (`INDEX_ID`) REFERENCES `IDXS` (`INDEX_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `NUCLEUS_TABLES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `NUCLEUS_TABLES` (
+ `CLASS_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TABLE_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TYPE` varchar(4) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `OWNER` varchar(2) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `VERSION` varchar(20) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `INTERFACE_NAME` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`CLASS_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PARTITIONS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PARTITIONS` (
+ `PART_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `LAST_ACCESS_TIME` int(11) NOT NULL,
+ `PART_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `SD_ID` bigint(20) DEFAULT NULL,
+ `TBL_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`PART_ID`),
+ UNIQUE KEY `UNIQUEPARTITION` (`PART_NAME`,`TBL_ID`),
+ KEY `PARTITIONS_N49` (`TBL_ID`),
+ KEY `PARTITIONS_N50` (`SD_ID`),
+ CONSTRAINT `PARTITIONS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`),
+ CONSTRAINT `PARTITIONS_FK2` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PARTITION_EVENTS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PARTITION_EVENTS` (
+ `PART_NAME_ID` bigint(20) NOT NULL,
+ `DB_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `EVENT_TIME` bigint(20) NOT NULL,
+ `EVENT_TYPE` int(11) NOT NULL,
+ `PARTITION_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`PART_NAME_ID`),
+ KEY `PARTITIONEVENTINDEX` (`PARTITION_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PARTITION_KEYS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PARTITION_KEYS` (
+ `TBL_ID` bigint(20) NOT NULL,
+ `PKEY_COMMENT` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PKEY_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PKEY_TYPE` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`TBL_ID`,`PKEY_NAME`),
+ KEY `PARTITION_KEYS_N49` (`TBL_ID`),
+ CONSTRAINT `PARTITION_KEYS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PARTITION_KEY_VALS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PARTITION_KEY_VALS` (
+ `PART_ID` bigint(20) NOT NULL,
+ `PART_KEY_VAL` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`PART_ID`,`INTEGER_IDX`),
+ KEY `PARTITION_KEY_VALS_N49` (`PART_ID`),
+ CONSTRAINT `PARTITION_KEY_VALS_FK1` FOREIGN KEY (`PART_ID`) REFERENCES `PARTITIONS` (`PART_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PARTITION_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PARTITION_PARAMS` (
+ `PART_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`PART_ID`,`PARAM_KEY`),
+ KEY `PARTITION_PARAMS_N49` (`PART_ID`),
+ CONSTRAINT `PARTITION_PARAMS_FK1` FOREIGN KEY (`PART_ID`) REFERENCES `PARTITIONS` (`PART_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PART_COL_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PART_COL_PRIVS` (
+ `PART_COLUMN_GRANT_ID` bigint(20) NOT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PART_ID` bigint(20) DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PART_COL_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`PART_COLUMN_GRANT_ID`),
+ KEY `PART_COL_PRIVS_N49` (`PART_ID`),
+ KEY `PARTITIONCOLUMNPRIVILEGEINDEX` (`PART_ID`,`COLUMN_NAME`,`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`PART_COL_PRIV`,`GRANTOR`,`GRANTOR_TYPE`),
+ CONSTRAINT `PART_COL_PRIVS_FK1` FOREIGN KEY (`PART_ID`) REFERENCES `PARTITIONS` (`PART_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `PART_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `PART_PRIVS` (
+ `PART_GRANT_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PART_ID` bigint(20) DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PART_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`PART_GRANT_ID`),
+ KEY `PARTPRIVILEGEINDEX` (`PART_ID`,`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`PART_PRIV`,`GRANTOR`,`GRANTOR_TYPE`),
+ KEY `PART_PRIVS_N49` (`PART_ID`),
+ CONSTRAINT `PART_PRIVS_FK1` FOREIGN KEY (`PART_ID`) REFERENCES `PARTITIONS` (`PART_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `ROLES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `ROLES` (
+ `ROLE_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `OWNER_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `ROLE_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`ROLE_ID`),
+ UNIQUE KEY `ROLEENTITYINDEX` (`ROLE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `ROLE_MAP`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `ROLE_MAP` (
+ `ROLE_GRANT_ID` bigint(20) NOT NULL,
+ `ADD_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `ROLE_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`ROLE_GRANT_ID`),
+ UNIQUE KEY `USERROLEMAPINDEX` (`PRINCIPAL_NAME`,`ROLE_ID`,`GRANTOR`,`GRANTOR_TYPE`),
+ KEY `ROLE_MAP_N49` (`ROLE_ID`),
+ CONSTRAINT `ROLE_MAP_FK1` FOREIGN KEY (`ROLE_ID`) REFERENCES `ROLES` (`ROLE_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SDS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SDS` (
+ `SD_ID` bigint(20) NOT NULL,
+ `CD_ID` bigint(20) DEFAULT NULL,
+ `INPUT_FORMAT` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `IS_COMPRESSED` bit(1) NOT NULL,
+ `IS_STOREDASSUBDIRECTORIES` bit(1) NOT NULL,
+ `LOCATION` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `NUM_BUCKETS` int(11) NOT NULL,
+ `OUTPUT_FORMAT` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `SERDE_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`SD_ID`),
+ KEY `SDS_N49` (`SERDE_ID`),
+ KEY `SDS_N50` (`CD_ID`),
+ CONSTRAINT `SDS_FK1` FOREIGN KEY (`SERDE_ID`) REFERENCES `SERDES` (`SERDE_ID`),
+ CONSTRAINT `SDS_FK2` FOREIGN KEY (`CD_ID`) REFERENCES `CDS` (`CD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SD_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SD_PARAMS` (
+ `SD_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` MEDIUMTEXT CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`SD_ID`,`PARAM_KEY`),
+ KEY `SD_PARAMS_N49` (`SD_ID`),
+ CONSTRAINT `SD_PARAMS_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SEQUENCE_TABLE`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SEQUENCE_TABLE` (
+ `SEQUENCE_NAME` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `NEXT_VAL` bigint(20) NOT NULL,
+ PRIMARY KEY (`SEQUENCE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SERDES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SERDES` (
+ `SERDE_ID` bigint(20) NOT NULL,
+ `NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `SLIB` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`SERDE_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SERDE_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SERDE_PARAMS` (
+ `SERDE_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` MEDIUMTEXT CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`SERDE_ID`,`PARAM_KEY`),
+ KEY `SERDE_PARAMS_N49` (`SERDE_ID`),
+ CONSTRAINT `SERDE_PARAMS_FK1` FOREIGN KEY (`SERDE_ID`) REFERENCES `SERDES` (`SERDE_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SKEWED_COL_NAMES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SKEWED_COL_NAMES` (
+ `SD_ID` bigint(20) NOT NULL,
+ `SKEWED_COL_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`SD_ID`,`INTEGER_IDX`),
+ KEY `SKEWED_COL_NAMES_N49` (`SD_ID`),
+ CONSTRAINT `SKEWED_COL_NAMES_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SKEWED_COL_VALUE_LOC_MAP`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SKEWED_COL_VALUE_LOC_MAP` (
+ `SD_ID` bigint(20) NOT NULL,
+ `STRING_LIST_ID_KID` bigint(20) NOT NULL,
+ `LOCATION` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`SD_ID`,`STRING_LIST_ID_KID`),
+ KEY `SKEWED_COL_VALUE_LOC_MAP_N49` (`STRING_LIST_ID_KID`),
+ KEY `SKEWED_COL_VALUE_LOC_MAP_N50` (`SD_ID`),
+ CONSTRAINT `SKEWED_COL_VALUE_LOC_MAP_FK2` FOREIGN KEY (`STRING_LIST_ID_KID`) REFERENCES `SKEWED_STRING_LIST` (`STRING_LIST_ID`),
+ CONSTRAINT `SKEWED_COL_VALUE_LOC_MAP_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SKEWED_STRING_LIST`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SKEWED_STRING_LIST` (
+ `STRING_LIST_ID` bigint(20) NOT NULL,
+ PRIMARY KEY (`STRING_LIST_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SKEWED_STRING_LIST_VALUES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SKEWED_STRING_LIST_VALUES` (
+ `STRING_LIST_ID` bigint(20) NOT NULL,
+ `STRING_LIST_VALUE` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`STRING_LIST_ID`,`INTEGER_IDX`),
+ KEY `SKEWED_STRING_LIST_VALUES_N49` (`STRING_LIST_ID`),
+ CONSTRAINT `SKEWED_STRING_LIST_VALUES_FK1` FOREIGN KEY (`STRING_LIST_ID`) REFERENCES `SKEWED_STRING_LIST` (`STRING_LIST_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SKEWED_VALUES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SKEWED_VALUES` (
+ `SD_ID_OID` bigint(20) NOT NULL,
+ `STRING_LIST_ID_EID` bigint(20) NOT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`SD_ID_OID`,`INTEGER_IDX`),
+ KEY `SKEWED_VALUES_N50` (`SD_ID_OID`),
+ KEY `SKEWED_VALUES_N49` (`STRING_LIST_ID_EID`),
+ CONSTRAINT `SKEWED_VALUES_FK2` FOREIGN KEY (`STRING_LIST_ID_EID`) REFERENCES `SKEWED_STRING_LIST` (`STRING_LIST_ID`),
+ CONSTRAINT `SKEWED_VALUES_FK1` FOREIGN KEY (`SD_ID_OID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SORT_COLS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `SORT_COLS` (
+ `SD_ID` bigint(20) NOT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `ORDER` int(11) NOT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`SD_ID`,`INTEGER_IDX`),
+ KEY `SORT_COLS_N49` (`SD_ID`),
+ CONSTRAINT `SORT_COLS_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TABLE_PARAMS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TABLE_PARAMS` (
+ `TBL_ID` bigint(20) NOT NULL,
+ `PARAM_KEY` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARAM_VALUE` MEDIUMTEXT CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`TBL_ID`,`PARAM_KEY`),
+ KEY `TABLE_PARAMS_N49` (`TBL_ID`),
+ CONSTRAINT `TABLE_PARAMS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TBLS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TBLS` (
+ `TBL_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `DB_ID` bigint(20) DEFAULT NULL,
+ `LAST_ACCESS_TIME` int(11) NOT NULL,
+ `OWNER` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `RETENTION` int(11) NOT NULL,
+ `SD_ID` bigint(20) DEFAULT NULL,
+ `TBL_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `VIEW_EXPANDED_TEXT` mediumtext,
+ `VIEW_ORIGINAL_TEXT` mediumtext,
+ `IS_REWRITE_ENABLED` bit(1) NOT NULL DEFAULT 0,
+ PRIMARY KEY (`TBL_ID`),
+ UNIQUE KEY `UNIQUETABLE` (`TBL_NAME`,`DB_ID`),
+ KEY `TBLS_N50` (`SD_ID`),
+ KEY `TBLS_N49` (`DB_ID`),
+ CONSTRAINT `TBLS_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`),
+ CONSTRAINT `TBLS_FK2` FOREIGN KEY (`DB_ID`) REFERENCES `DBS` (`DB_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TBL_COL_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TBL_COL_PRIVS` (
+ `TBL_COLUMN_GRANT_ID` bigint(20) NOT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_COL_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`TBL_COLUMN_GRANT_ID`),
+ KEY `TABLECOLUMNPRIVILEGEINDEX` (`TBL_ID`,`COLUMN_NAME`,`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`TBL_COL_PRIV`,`GRANTOR`,`GRANTOR_TYPE`),
+ KEY `TBL_COL_PRIVS_N49` (`TBL_ID`),
+ CONSTRAINT `TBL_COL_PRIVS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TBL_PRIVS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TBL_PRIVS` (
+ `TBL_GRANT_ID` bigint(20) NOT NULL,
+ `CREATE_TIME` int(11) NOT NULL,
+ `GRANT_OPTION` smallint(6) NOT NULL,
+ `GRANTOR` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `GRANTOR_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `PRINCIPAL_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_PRIV` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TBL_ID` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`TBL_GRANT_ID`),
+ KEY `TBL_PRIVS_N49` (`TBL_ID`),
+ KEY `TABLEPRIVILEGEINDEX` (`TBL_ID`,`PRINCIPAL_NAME`,`PRINCIPAL_TYPE`,`TBL_PRIV`,`GRANTOR`,`GRANTOR_TYPE`),
+ CONSTRAINT `TBL_PRIVS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TAB_COL_STATS`
+--
+CREATE TABLE IF NOT EXISTS `TAB_COL_STATS` (
+ `CS_ID` bigint(20) NOT NULL,
+ `DB_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TABLE_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `COLUMN_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TBL_ID` bigint(20) NOT NULL,
+ `LONG_LOW_VALUE` bigint(20),
+ `LONG_HIGH_VALUE` bigint(20),
+ `DOUBLE_HIGH_VALUE` double(53,4),
+ `DOUBLE_LOW_VALUE` double(53,4),
+ `BIG_DECIMAL_LOW_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `BIG_DECIMAL_HIGH_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `NUM_NULLS` bigint(20) NOT NULL,
+ `NUM_DISTINCTS` bigint(20),
+ `AVG_COL_LEN` double(53,4),
+ `MAX_COL_LEN` bigint(20),
+ `NUM_TRUES` bigint(20),
+ `NUM_FALSES` bigint(20),
+ `LAST_ANALYZED` bigint(20) NOT NULL,
+ PRIMARY KEY (`CS_ID`),
+ CONSTRAINT `TAB_COL_STATS_FK` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `PART_COL_STATS`
+--
+CREATE TABLE IF NOT EXISTS `PART_COL_STATS` (
+ `CS_ID` bigint(20) NOT NULL,
+ `DB_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `TABLE_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PARTITION_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `COLUMN_TYPE` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `PART_ID` bigint(20) NOT NULL,
+ `LONG_LOW_VALUE` bigint(20),
+ `LONG_HIGH_VALUE` bigint(20),
+ `DOUBLE_HIGH_VALUE` double(53,4),
+ `DOUBLE_LOW_VALUE` double(53,4),
+ `BIG_DECIMAL_LOW_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `BIG_DECIMAL_HIGH_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `NUM_NULLS` bigint(20) NOT NULL,
+ `NUM_DISTINCTS` bigint(20),
+ `AVG_COL_LEN` double(53,4),
+ `MAX_COL_LEN` bigint(20),
+ `NUM_TRUES` bigint(20),
+ `NUM_FALSES` bigint(20),
+ `LAST_ANALYZED` bigint(20) NOT NULL,
+ PRIMARY KEY (`CS_ID`),
+ CONSTRAINT `PART_COL_STATS_FK` FOREIGN KEY (`PART_ID`) REFERENCES `PARTITIONS` (`PART_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE INDEX PCS_STATS_IDX ON PART_COL_STATS (DB_NAME,TABLE_NAME,COLUMN_NAME,PARTITION_NAME) USING BTREE;
+
+--
+-- Table structure for table `TYPES`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TYPES` (
+ `TYPES_ID` bigint(20) NOT NULL,
+ `TYPE_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TYPE1` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `TYPE2` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ PRIMARY KEY (`TYPES_ID`),
+ UNIQUE KEY `UNIQUE_TYPE` (`TYPE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `TYPE_FIELDS`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE IF NOT EXISTS `TYPE_FIELDS` (
+ `TYPE_NAME` bigint(20) NOT NULL,
+ `COMMENT` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
+ `FIELD_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `FIELD_TYPE` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ `INTEGER_IDX` int(11) NOT NULL,
+ PRIMARY KEY (`TYPE_NAME`,`FIELD_NAME`),
+ KEY `TYPE_FIELDS_N49` (`TYPE_NAME`),
+ CONSTRAINT `TYPE_FIELDS_FK1` FOREIGN KEY (`TYPE_NAME`) REFERENCES `TYPES` (`TYPES_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Table `MASTER_KEYS` for classes [org.apache.hadoop.hive.metastore.model.MMasterKey]
+CREATE TABLE IF NOT EXISTS `MASTER_KEYS`
+(
+ `KEY_ID` INTEGER NOT NULL AUTO_INCREMENT,
+ `MASTER_KEY` VARCHAR(767) BINARY NULL,
+ PRIMARY KEY (`KEY_ID`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1;
+
+-- Table `DELEGATION_TOKENS` for classes [org.apache.hadoop.hive.metastore.model.MDelegationToken]
+CREATE TABLE IF NOT EXISTS `DELEGATION_TOKENS`
+(
+ `TOKEN_IDENT` VARCHAR(767) BINARY NOT NULL,
+ `TOKEN` VARCHAR(767) BINARY NULL,
+ PRIMARY KEY (`TOKEN_IDENT`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for VERSION
+--
+CREATE TABLE IF NOT EXISTS `VERSION` (
+ `VER_ID` BIGINT NOT NULL,
+ `SCHEMA_VERSION` VARCHAR(127) NOT NULL,
+ `VERSION_COMMENT` VARCHAR(255),
+ PRIMARY KEY (`VER_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table FUNCS
+--
+CREATE TABLE IF NOT EXISTS `FUNCS` (
+ `FUNC_ID` BIGINT(20) NOT NULL,
+ `CLASS_NAME` VARCHAR(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `CREATE_TIME` INT(11) NOT NULL,
+ `DB_ID` BIGINT(20),
+ `FUNC_NAME` VARCHAR(128) CHARACTER SET latin1 COLLATE latin1_bin,
+ `FUNC_TYPE` INT(11) NOT NULL,
+ `OWNER_NAME` VARCHAR(128) CHARACTER SET latin1 COLLATE latin1_bin,
+ `OWNER_TYPE` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,
+ PRIMARY KEY (`FUNC_ID`),
+ UNIQUE KEY `UNIQUEFUNCTION` (`FUNC_NAME`, `DB_ID`),
+ KEY `FUNCS_N49` (`DB_ID`),
+ CONSTRAINT `FUNCS_FK1` FOREIGN KEY (`DB_ID`) REFERENCES `DBS` (`DB_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table FUNC_RU
+--
+CREATE TABLE IF NOT EXISTS `FUNC_RU` (
+ `FUNC_ID` BIGINT(20) NOT NULL,
+ `RESOURCE_TYPE` INT(11) NOT NULL,
+ `RESOURCE_URI` VARCHAR(4000) CHARACTER SET latin1 COLLATE latin1_bin,
+ `INTEGER_IDX` INT(11) NOT NULL,
+ PRIMARY KEY (`FUNC_ID`, `INTEGER_IDX`),
+ CONSTRAINT `FUNC_RU_FK1` FOREIGN KEY (`FUNC_ID`) REFERENCES `FUNCS` (`FUNC_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `NOTIFICATION_LOG`
+(
+ `NL_ID` BIGINT(20) NOT NULL,
+ `EVENT_ID` BIGINT(20) NOT NULL,
+ `EVENT_TIME` INT(11) NOT NULL,
+ `EVENT_TYPE` varchar(32) NOT NULL,
+ `DB_NAME` varchar(128),
+ `TBL_NAME` varchar(256),
+ `MESSAGE` longtext,
+ `MESSAGE_FORMAT` varchar(16),
+ PRIMARY KEY (`NL_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `NOTIFICATION_SEQUENCE`
+(
+ `NNI_ID` BIGINT(20) NOT NULL,
+ `NEXT_EVENT_ID` BIGINT(20) NOT NULL,
+ PRIMARY KEY (`NNI_ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `KEY_CONSTRAINTS`
+(
+ `CHILD_CD_ID` BIGINT,
+ `CHILD_INTEGER_IDX` INT(11),
+ `CHILD_TBL_ID` BIGINT,
+ `PARENT_CD_ID` BIGINT NOT NULL,
+ `PARENT_INTEGER_IDX` INT(11) NOT NULL,
+ `PARENT_TBL_ID` BIGINT NOT NULL,
+ `POSITION` BIGINT NOT NULL,
+ `CONSTRAINT_NAME` VARCHAR(400) NOT NULL,
+ `CONSTRAINT_TYPE` SMALLINT(6) NOT NULL,
+ `UPDATE_RULE` SMALLINT(6),
+ `DELETE_RULE` SMALLINT(6),
+ `ENABLE_VALIDATE_RELY` SMALLINT(6) NOT NULL,
+ PRIMARY KEY (`CONSTRAINT_NAME`, `POSITION`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE INDEX `CONSTRAINTS_PARENT_TABLE_ID_INDEX` ON KEY_CONSTRAINTS (`PARENT_TBL_ID`) USING BTREE;
+
+--
+-- Tables for transaction management
+--
+
+CREATE TABLE TXNS (
+ TXN_ID bigint PRIMARY KEY,
+ TXN_STATE char(1) NOT NULL,
+ TXN_STARTED bigint NOT NULL,
+ TXN_LAST_HEARTBEAT bigint NOT NULL,
+ TXN_USER varchar(128) NOT NULL,
+ TXN_HOST varchar(128) NOT NULL,
+ TXN_AGENT_INFO varchar(128),
+ TXN_META_INFO varchar(128),
+ TXN_HEARTBEAT_COUNT int
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE TXN_COMPONENTS (
+ TC_TXNID bigint NOT NULL,
+ TC_DATABASE varchar(128) NOT NULL,
+ TC_TABLE varchar(128) NOT NULL,
+ TC_PARTITION varchar(767),
+ TC_OPERATION_TYPE char(1) NOT NULL,
+ FOREIGN KEY (TC_TXNID) REFERENCES TXNS (TXN_ID)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE INDEX TC_TXNID_INDEX ON TXN_COMPONENTS (TC_TXNID);
+
+CREATE TABLE COMPLETED_TXN_COMPONENTS (
+ CTC_TXNID bigint NOT NULL,
+ CTC_DATABASE varchar(128) NOT NULL,
+ CTC_TABLE varchar(256),
+ CTC_PARTITION varchar(767)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE NEXT_TXN_ID (
+ NTXN_NEXT bigint NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO NEXT_TXN_ID VALUES(1);
+
+CREATE TABLE HIVE_LOCKS (
+ HL_LOCK_EXT_ID bigint NOT NULL,
+ HL_LOCK_INT_ID bigint NOT NULL,
+ HL_TXNID bigint,
+ HL_DB varchar(128) NOT NULL,
+ HL_TABLE varchar(128),
+ HL_PARTITION varchar(767),
+ HL_LOCK_STATE char(1) not null,
+ HL_LOCK_TYPE char(1) not null,
+ HL_LAST_HEARTBEAT bigint NOT NULL,
+ HL_ACQUIRED_AT bigint,
+ HL_USER varchar(128) NOT NULL,
+ HL_HOST varchar(128) NOT NULL,
+ HL_HEARTBEAT_COUNT int,
+ HL_AGENT_INFO varchar(128),
+ HL_BLOCKEDBY_EXT_ID bigint,
+ HL_BLOCKEDBY_INT_ID bigint,
+ PRIMARY KEY(HL_LOCK_EXT_ID, HL_LOCK_INT_ID),
+ KEY HIVE_LOCK_TXNID_INDEX (HL_TXNID)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE INDEX HL_TXNID_IDX ON HIVE_LOCKS (HL_TXNID);
+
+CREATE TABLE NEXT_LOCK_ID (
+ NL_NEXT bigint NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO NEXT_LOCK_ID VALUES(1);
+
+CREATE TABLE COMPACTION_QUEUE (
+ CQ_ID bigint PRIMARY KEY,
+ CQ_DATABASE varchar(128) NOT NULL,
+ CQ_TABLE varchar(128) NOT NULL,
+ CQ_PARTITION varchar(767),
+ CQ_STATE char(1) NOT NULL,
+ CQ_TYPE char(1) NOT NULL,
+ CQ_TBLPROPERTIES varchar(2048),
+ CQ_WORKER_ID varchar(128),
+ CQ_START bigint,
+ CQ_RUN_AS varchar(128),
+ CQ_HIGHEST_TXN_ID bigint,
+ CQ_META_INFO varbinary(2048),
+ CQ_HADOOP_JOB_ID varchar(32)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE COMPLETED_COMPACTIONS (
+ CC_ID bigint PRIMARY KEY,
+ CC_DATABASE varchar(128) NOT NULL,
+ CC_TABLE varchar(128) NOT NULL,
+ CC_PARTITION varchar(767),
+ CC_STATE char(1) NOT NULL,
+ CC_TYPE char(1) NOT NULL,
+ CC_TBLPROPERTIES varchar(2048),
+ CC_WORKER_ID varchar(128),
+ CC_START bigint,
+ CC_END bigint,
+ CC_RUN_AS varchar(128),
+ CC_HIGHEST_TXN_ID bigint,
+ CC_META_INFO varbinary(2048),
+ CC_HADOOP_JOB_ID varchar(32)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE NEXT_COMPACTION_QUEUE_ID (
+ NCQ_NEXT bigint NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO NEXT_COMPACTION_QUEUE_ID VALUES(1);
+
+CREATE TABLE AUX_TABLE (
+ MT_KEY1 varchar(128) NOT NULL,
+ MT_KEY2 bigint NOT NULL,
+ MT_COMMENT varchar(255),
+ PRIMARY KEY(MT_KEY1, MT_KEY2)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE WRITE_SET (
+ WS_DATABASE varchar(128) NOT NULL,
+ WS_TABLE varchar(128) NOT NULL,
+ WS_PARTITION varchar(767),
+ WS_TXNID bigint NOT NULL,
+ WS_COMMIT_ID bigint NOT NULL,
+ WS_OPERATION_TYPE char(1) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- -----------------------------------------------------------------
+-- Record schema version. Should be the last step in the init script
+-- -----------------------------------------------------------------
+INSERT INTO VERSION (VER_ID, SCHEMA_VERSION, VERSION_COMMENT) VALUES (1, '2.3.0', 'Hive release version 2.3.0');
+
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2012-08-23 0:56:31
diff --git a/docs/database/submarine-data.sql b/docs/database/submarine-data.sql
new file mode 100644
index 0000000000000000000000000000000000000000..93ed13d0d7ff400519ab36aedd4ec07122201cf9
--- /dev/null
+++ b/docs/database/submarine-data.sql
@@ -0,0 +1,96 @@
+-- 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.
+
+-- ----------------------------
+-- Records of sys_dict
+-- ----------------------------
+INSERT INTO `sys_dict` VALUES ('ca2dd544ca4c11e9a71e0242ac110002','SYS_USER_SEX','Sys user sex','submarine system dict, Do not modify.',0,0,NULL,'2019-08-29 11:04:36',NULL,'2019-09-01 01:08:12');
+INSERT INTO `sys_dict` VALUES ('f405a7b1cc5411e9af810242ac110002','SYS_USER_STATUS','Sys user status','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('3a1ed33ae83611e9ab840242ac110002','PROJECT_TYPE','Project machine learning type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('8a101495e84011e9ab840242ac110002','PROJECT_VISIBILITY','Project visibility type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('8f0439c9e84011e9ab840242ac110002','PROJECT_PERMISSION','Project permission type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+
+-- ----------------------------
+-- Records of sys_dict_item
+-- ----------------------------
+INSERT INTO `sys_dict_item` VALUES ('27ef1080cc5511e9af810242ac110002','SYS_USER_STATUS_AVAILABLE','Available','SYS_USER_STATUS','submarine system dict, Do not modify.',1,0,NULL,'2019-09-01 01:09:32',NULL,'2019-09-01 01:13:19');
+INSERT INTO `sys_dict_item` VALUES ('4c5d736acc5511e9af810242ac110002','SYS_USER_STATUS_LOCKED','Locked','SYS_USER_STATUS','submarine system dict, Do not modify.',2,0,NULL,'2019-09-01 01:10:33',NULL,'2019-09-01 01:12:53');
+INSERT INTO `sys_dict_item` VALUES ('6d5ae3b2cc5511e9af810242ac110002','SYS_USER_STATUS_REGISTERED','New Registered','SYS_USER_STATUS','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
+INSERT INTO `sys_dict_item` VALUES ('d018e2b0ca4c11e9a71e0242ac110002','SYS_USER_SEX_MALE','Male','SYS_USER_SEX','submarine system dict, Do not modify.',1,0,NULL,'2019-08-29 11:04:46',NULL,'2019-09-01 00:53:54');
+INSERT INTO `sys_dict_item` VALUES ('d94410adca4c11e9a71e0242ac110002','SYS_USER_SEX_FEMALE','Female','SYS_USER_SEX','submarine system dict, Do not modify.',2,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('7b9aafa0e83611e9ab840242ac110002','PROJECT_TYPE_NOTEBOOK','notebook','PROJECT_TYPE','submarine system dict, Do not modify.',1,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('8229a76be83611e9ab840242ac110002','PROJECT_TYPE_PYTHON','python','PROJECT_TYPE','submarine system dict, Do not modify.',2,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('ac80ab12e83611e9ab840242ac110002','PROJECT_TYPE_R','R','PROJECT_TYPE','submarine system dict, Do not modify.',3,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('b1070158e83611e9ab840242ac110002','PROJECT_TYPE_SCALA','scala','PROJECT_TYPE','submarine system dict, Do not modify.',4,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('8c53870be83611e9ab840242ac110002','PROJECT_TYPE_TENSORFLOW','tensorflow','PROJECT_TYPE','submarine system dict, Do not modify.',5,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('90ca63dfe83611e9ab840242ac110002','PROJECT_TYPE_PYTORCH','pytorch','PROJECT_TYPE','submarine system dict, Do not modify.',6,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('2ed844fae84111e9ab840242ac110002','PROJECT_VISIBILITY_PRIVATE','private','PROJECT_VISIBILITY','submarine system dict, Do not modify.',1,0,NULL,'2019-09-01 01:09:32',NULL,'2019-09-01 01:13:19');
+INSERT INTO `sys_dict_item` VALUES ('341d5a35e84111e9ab840242ac110002','PROJECT_VISIBILITY_TEAM','team','PROJECT_VISIBILITY','submarine system dict, Do not modify.',2,0,NULL,'2019-09-01 01:10:33',NULL,'2019-09-01 01:12:53');
+INSERT INTO `sys_dict_item` VALUES ('3866b369e84111e9ab840242ac110002','PROJECT_VISIBILITY_PUBLIC','public','PROJECT_VISIBILITY','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
+INSERT INTO `sys_dict_item` VALUES ('3cc1a373e84111e9ab840242ac110002','PROJECT_PERMISSION_VIEW','can view','PROJECT_PERMISSION','submarine system dict, Do not modify.',1,0,NULL,'2019-09-01 01:09:32',NULL,'2019-09-01 01:13:19');
+INSERT INTO `sys_dict_item` VALUES ('44e90f6ce84111e9ab840242ac110002','PROJECT_PERMISSION_EDIT','can edit','PROJECT_PERMISSION','submarine system dict, Do not modify.',2,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
+INSERT INTO `sys_dict_item` VALUES ('40dbb5ece84111e9ab840242ac110002','PROJECT_PERMISSION_EXECUTE','can execute','PROJECT_PERMISSION','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:10:33',NULL,'2019-09-01 01:12:53');
+
+-- ----------------------------
+-- Records of sys_department
+-- ----------------------------
+INSERT INTO `sys_department` VALUES ('e3d69d19c8d211e98edc0242ac110002','A','Company',NULL,0,'','0',NULL,'2019-08-27 13:59:30',NULL,'2019-08-27 14:02:05');
+INSERT INTO `sys_department` VALUES ('eec10fe9c8d211e98edc0242ac110002','AA','DepartmentA','A',0,'','0',NULL,'2019-08-27 13:59:48',NULL,'2019-08-27 14:04:11');
+INSERT INTO `sys_department` VALUES ('f8b42e19c8d211e98edc0242ac110002','AB','DepartmentB','A',0,'','0',NULL,'2019-08-27 14:00:05',NULL,'2019-08-27 14:07:19');
+INSERT INTO `sys_department` VALUES ('13a1916dc8d311e98edc0242ac110002','ABA','GroupA','AB',0,'','0',NULL,'2019-08-27 14:00:50',NULL,'2019-08-27 14:09:21');
+INSERT INTO `sys_department` VALUES ('1bc0cd98c8d311e98edc0242ac110002','AAA','GroupB','AA',0,'','0',NULL,'2019-08-27 14:01:04',NULL,'2019-08-29 16:48:56');
+
+-- ----------------------------
+-- Records of sys_user
+-- ----------------------------
+INSERT INTO `sys_user` VALUES ('e9ca23d68d884d4ebb19d07889727dae', 'admin', 'administrator', '21232f297a57a5a743894a0e4a801fc3', 'avatar.png', '2018-12-05 00:00:00', NULL, 'dev@submarine.org', '18566666661', NULL, NULL, NULL, 1, 'admin', '2019-07-05 14:47:22', 'admin', '2019-07-05 14:47:22');
+
+-- ----------------------------
+-- Records of team
+-- ----------------------------
+INSERT INTO `team` VALUES ('e9ca23d68d884d4ebb19d07889721234', 'admin', 'Submarine', 'admin', '2020-05-06 14:00:05', 'Jack', '2020-05-06 14:00:14');
+
+-- ----------------------------
+-- Records of metrics
+-- ----------------------------
+INSERT INTO `metrics` (`id`, `key`, `value`, `worker_index`, `timestamp`, `step`, `is_nan`) VALUES
+('application_123651651', 'score', 0.666667, 'worker-1', 1569139525097, 0, 0),
+('application_123651651', 'score', 0.666670, 'worker-1', 1569149139731, 1, 0),
+('experiment_1595332719154_0001', 'score', 0.666667, 'worker-1', 1569169376482, 0, 0),
+('experiment_1595332719154_0001', 'score', 0.666671, 'worker-1', 1569236290721, 0, 0),
+('experiment_1595332719154_0001', 'score', 0.666680, 'worker-1', 1569236466722, 0, 0);
+
+-- ----------------------------
+-- Records of params
+-- ----------------------------
+INSERT INTO `params` (`id`, `key`, `value`, `worker_index`) VALUES
+('application_123651651', 'max_iter', '100', 'worker-1'),
+('application_123456898', 'n_jobs', '5', 'worker-1'),
+('application_123456789', 'alpha', '20', 'worker-1'),
+('experiment_1595332719154_0001', 'max_iter', '100', 'worker-1'),
+('experiment_1595332719154_0002', 'n_jobs', '5', 'worker-1'),
+('experiment_1595332719154_0003', 'alpha', '20', 'worker-1');
+
+-- ----------------------------
+-- Records of environment
+-- ----------------------------
+INSERT INTO `environment` VALUES
+('environment_1600862964725_0001', 'notebook-env', '{"name":"notebook-env","dockerImage":"apache/submarine:jupyter-notebook-0.5.0","kernelSpec":{"name":"submarine_jupyter_py3","channels":["defaults"],"dependencies":[]}}', 'admin', '2020-09-21 14:00:05', 'admin', '2020-09-21 14:00:14');
+
+-- ----------------------------
+-- Records of experiment_templates
+-- ----------------------------
+INSERT INTO `experiment_template` (`id`, `experimentTemplate_name`, `experimentTemplate_spec`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES
+('experimentTemplate_1599498007985_0013', 'tf-mnist', '{\"name\": \"tf-mnist\", \"author\": \"author\", \"parameters\": [{\"name\": \"learning_rate\", \"value\": \"0.2\", \"required\": \"false\", \"description\": \"The parameter of train mnist.\"}, {\"name\": \"batch_size\", \"value\": \"150\", \"required\": \"false\", \"description\": \"The parameter of train mnist.\"}, {\"name\": \"experiment_name\", \"required\": \"true\", \"description\": \"experiment name, you should change it to avoid duplication with other experiment names.\"}, {\"name\": \"spec.Ps.replicas\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Ps.resourceMap.cpu\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Ps.resourceMap.memory\", \"value\": \"1000M\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.replicas\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.resourceMap.cpu\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.resourceMap.memory\", \"value\": \"1000M\", \"required\": \"false\", \"description\": \"\"}], \"description\": \"This is a template to run tf-mnist.\", \"experimentSpec\": {\"meta\": {\"cmd\": \"python /var/tf_mnist/mnist_with_summaries.py --log_dir=/train/log --learning_rate={{learning_rate}} --batch_size={{batch_size}}\", \"name\": \"{{experiment_name}}\", \"envVars\": {\"ENV1\": \"ENV1\"}, \"framework\": \"TensorFlow\", \"namespace\": \"default\"}, \"spec\": {\"Ps\": {\"replicas\": 1, \"resources\": \"cpu=1,memory=1000M\", \"resourceMap\": {\"cpu\": \"1\", \"memory\": \"1000M\"}}, \"Worker\": {\"replicas\": 1, \"resources\": \"cpu=1,memory=1000M\", \"resourceMap\": {\"cpu\": \"1\", \"memory\": \"1000M\"}}}, \"environment\": {\"image\": \"apache/submarine:tf-mnist-with-summaries-1.0\"}}}', NULL, '2020-09-10 16:31:32', NULL, '2020-10-19 17:05:21');
+
+INSERT INTO `experiment_template` (`id`, `experimentTemplate_name`, `experimentTemplate_spec`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES('experimentTemplate_1606489231336_0014', 'pytorch-mnist', '{\"name\": \"pytorch-mnist\", \"author\": \"author\", \"parameters\": [{\"name\": \"experiment_name\", \"required\": \"true\", \"description\": \"experiment name\"}, {\"name\": \"spec.Master.replicas\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Master.resourceMap.cpu\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Master.resourceMap.memory\", \"value\": \"1024M\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.replicas\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.resourceMap.cpu\", \"value\": \"1\", \"required\": \"false\", \"description\": \"\"}, {\"name\": \"spec.Worker.resourceMap.memory\", \"value\": \"1024M\", \"required\": \"false\", \"description\": \"\"}], \"description\": \"This is a template to run pytorch-mnist\\n\", \"experimentSpec\": {\"meta\": {\"cmd\": \"python /var/mnist.py --backend gloo\", \"name\": \"{{experiment_name}}\", \"envVars\": {\"ENV_1\": \"ENV1\"}, \"framework\": \"PyTorch\", \"namespace\": \"default\"}, \"spec\": {\"Master\": {\"replicas\": 1, \"resources\": \"cpu=1,memory=1024M\", \"resourceMap\": {\"cpu\": \"1\", \"memory\": \"1024M\"}}, \"Worker\": {\"replicas\": 1, \"resources\": \"cpu=1,memory=1024M\", \"resourceMap\": {\"cpu\": \"1\", \"memory\": \"1024M\"}}}, \"environment\": {\"image\": \"apache/submarine:pytorch-dist-mnist-1.0\"}}}', NULL, '2020-11-29 17:56:10', NULL, '2020-11-29 17:56:10');
diff --git a/docs/database/submarine.sql b/docs/database/submarine.sql
new file mode 100644
index 0000000000000000000000000000000000000000..76dfc490ed709b6b2f2ec0b9b6107f14e6a3a194
--- /dev/null
+++ b/docs/database/submarine.sql
@@ -0,0 +1,281 @@
+-- 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.
+
+-- ----------------------------
+-- Table structure for sys_dict
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict`;
+CREATE TABLE `sys_dict` (
+ `id` varchar(32) NOT NULL,
+ `dict_code` varchar(32) NOT NULL COMMENT 'dict code',
+ `dict_name` varchar(32) NOT NULL COMMENT 'dict name',
+ `description` varchar(255) default NULL COMMENT 'dict description',
+ `deleted` int(1) default 0 COMMENT 'delete status(0:normal, 1:already deleted)',
+ `type` int(1) default 0 COMMENT 'dict type (0:string,1:number)',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `UK_SYS_DICT_DICT_CODE` (`dict_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for sys_dict_item
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict_item`;
+CREATE TABLE `sys_dict_item` (
+ `id` varchar(32) NOT NULL,
+ `item_code` varchar(32) NOT NULL COMMENT 'dict item code',
+ `item_name` varchar(32) NOT NULL COMMENT 'dict item name',
+ `dict_code` varchar(32) NOT NULL COMMENT 'dict code',
+ `description` varchar(255) default NULL COMMENT 'description',
+ `sort_order` int(3) default 0 COMMENT 'sort order',
+ `deleted` int(1) default 0 COMMENT 'delete status(0:normal,1:already deleted)',
+ `create_by` varchar(32) default NULL,
+ `create_time` datetime default NULL,
+ `update_by` varchar(32) default NULL,
+ `update_time` datetime default NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `UK_SYS_DICT_ITEM_CODE` (`item_code`)/*,
+ CONSTRAINT `FK_SYS_DICT_ITEM_DICT_CODE` FOREIGN KEY (`dict_code`) REFERENCES `sys_dict` (`dict_code`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for system department
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_department`;
+CREATE TABLE `sys_department` (
+ `id` varchar(32) NOT NULL COMMENT 'ID',
+ `dept_code` varchar(32) NOT NULL COMMENT 'department code',
+ `dept_name` varchar(64) NOT NULL COMMENT 'department name',
+ `parent_code` varchar(32) default NULL COMMENT 'parent dept code',
+ `sort_order` int(3) default 0 COMMENT 'sort order',
+ `description` varchar(255) COMMENT 'description',
+ `deleted` varchar(1) default 0 COMMENT 'delete status(0:normal,1:already deleted)',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `UK_DEPT_CODE` (`dept_code`)/*,
+ CONSTRAINT `FK_SYS_DEPT_PARENT_CODE` FOREIGN KEY (`parent_code`) REFERENCES `sys_department` (`dept_code`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for sys_user
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user`;
+CREATE TABLE `sys_user` (
+ `id` varchar(32) NOT NULL COMMENT 'id',
+ `user_name` varchar(32) NOT NULL COMMENT 'login name',
+ `real_name` varchar(64) NOT NULL COMMENT 'real name',
+ `password` varchar(255) NOT NULL COMMENT 'password',
+ `avatar` varchar(255) default NULL COMMENT 'avatar',
+ `birthday` datetime default NULL COMMENT 'birthday',
+ `sex` varchar(32) default NULL COMMENT 'sex',
+ `email` varchar(32) default NULL COMMENT 'email',
+ `phone` varchar(32) default NULL COMMENT 'telphone',
+ `dept_code` varchar(32) default NULL COMMENT 'department code',
+ `role_code` varchar(32) default NULL COMMENT 'role code',
+ `status` varchar(32) default NULL COMMENT 'status',
+ `deleted` int(1) default 0 COMMENT 'deleted status(0:normal, 1:already deleted)',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `sys_user_name` (`user_name`)/*,
+ CONSTRAINT `FK_SYS_USER_DEPT_CODE` FOREIGN KEY (`dept_code`) REFERENCES `sys_department` (`dept_code`),
+ CONSTRAINT `FK_SYS_USER_SEX` FOREIGN KEY (`sex`) REFERENCES `sys_dict_item` (`item_code`),
+ CONSTRAINT `FK_SYS_USER_STATUS` FOREIGN KEY (`status`) REFERENCES `sys_dict_item` (`item_code`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for sys_message
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_message`;
+CREATE TABLE `sys_message` (
+ `id` varchar(32) NOT NULL COMMENT 'id',
+ `sender` varchar(32) default NULL COMMENT 'sender user',
+ `receiver` varchar(32) default NULL COMMENT 'receiver user',
+ `type` varchar(32) default NULL COMMENT 'dict_code:MESSAGE_TYPE',
+ `context` text COMMENT 'message context',
+ `status` int(1) default 0 COMMENT '0:unread, 1:read',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`)/*,
+ CONSTRAINT `FK_SYS_MSG_SENDER` FOREIGN KEY (`sender`) REFERENCES `sys_user` (`user_name`),
+ CONSTRAINT `FK_SYS_MSG_RECEIVER` FOREIGN KEY (`receiver`) REFERENCES `sys_user` (`user_name`),
+ CONSTRAINT `FK_SYS_MSG_TYPE` FOREIGN KEY (`type`) REFERENCES `sys_dict_item` (`item_code`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for team
+-- ----------------------------
+DROP TABLE IF EXISTS `team`;
+CREATE TABLE `team` (
+ `id` varchar(32) NOT NULL,
+ `owner` varchar(100) NOT NULL COMMENT 'owner name',
+ `team_name` varchar(64) NOT NULL COMMENT 'team name',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `UK_TEAM_NAME` (`team_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for team_member
+-- ----------------------------
+DROP TABLE IF EXISTS `team_member`;
+CREATE TABLE `team_member` (
+ `id` varchar(32) NOT NULL,
+ `team_id` varchar(32) NOT NULL COMMENT 'team id',
+ `team_name` varchar(64) NOT NULL COMMENT 'team name',
+ `member` varchar(100) NOT NULL COMMENT 'member name',
+ `inviter` int(1) default 0 COMMENT '0:inviter, 1:accept',
+ `create_by` varchar(32) default NULL,
+ `create_time` datetime default NULL,
+ `update_by` varchar(32) default NULL,
+ `update_time` datetime default NULL,
+ PRIMARY KEY (`id`)/*,
+ CONSTRAINT `FK_TEAM_MEMBER_USER` FOREIGN KEY (`member`) REFERENCES `sys_user` (`user_name`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for project
+-- ----------------------------
+DROP TABLE IF EXISTS `project`;
+CREATE TABLE `project` (
+ `id` varchar(32) NOT NULL,
+ `name` varchar(100) NOT NULL COMMENT 'project name',
+ `visibility` varchar(32) default NULL COMMENT 'dict_code:PROJECT_VISIBILITY',
+ `permission` varchar(32) default NULL COMMENT 'dict_code:PROJECT_PERMISSION',
+ `type` varchar(32) default NULL COMMENT 'dict_code:PROJECT_TYPE',
+ `description` varchar(255) COMMENT 'description',
+ `user_name` varchar(32) NOT NULL COMMENT 'owner user id',
+ `team_name` varchar(32) default NULL COMMENT 'team name',
+ `tags` varchar(128) default NULL COMMENT 'Comma separated tag',
+ `star_num` int(8) default 0 COMMENT 'star number',
+ `like_num` int(8) default 0 COMMENT 'like number',
+ `message_num` int(8) default 0 COMMENT 'message number',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`)/*,
+ CONSTRAINT `FK_PROJECT_TYPE` FOREIGN KEY (`type`) REFERENCES `sys_dict_item` (`item_code`),
+ CONSTRAINT `FK_PROJECT_TEAM_NAME` FOREIGN KEY (`team_name`) REFERENCES `team` (`team_name`),
+ CONSTRAINT `FK_PROJECT_USER_NAME` FOREIGN KEY (`user_name`) REFERENCES `sys_user` (`user_name`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for project_files
+-- ----------------------------
+DROP TABLE IF EXISTS `project_files`;
+CREATE TABLE `project_files` (
+ `id` varchar(32) NOT NULL,
+ `project_id` varchar(32) NOT NULL COMMENT 'project id',
+ `file_name` varchar(128) NOT NULL COMMENT '/path/.../file.suffix',
+ `file_content` text default NULL COMMENT 'file content',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`)/*,
+ CONSTRAINT `FK_PROJECT_FILES_PRJ_ID` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`)*/
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for jobs
+-- ----------------------------
+DROP TABLE IF EXISTS `job`;
+CREATE TABLE `job` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `job_id` varchar(64) default NULL COMMENT 'job id',
+ `job_name` varchar(64) NOT NULL COMMENT 'job name',
+ `job_type` varchar(64) NOT NULL COMMENT 'job type',
+ `job_namespace` varchar(32) default NULL COMMENT 'job namespace',
+ `job_status` varchar(32) default NULL COMMENT 'job status',
+ `job_final_status` varchar(32) default NULL COMMENT 'job final status',
+ `user_name` varchar(32) default NULL COMMENT 'user name',
+ `create_by` varchar(32) default NULL COMMENT 'create user',
+ `create_time` datetime default NULL COMMENT 'create time',
+ `update_by` varchar(32) default NULL COMMENT 'last update user',
+ `update_time` datetime default NULL COMMENT 'last update time',
+ PRIMARY KEY (`id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for environment
+-- ----------------------------
+DROP TABLE IF EXISTS `environment`;
+CREATE TABLE `environment` (
+ `id` varchar(64) NOT NULL COMMENT 'Id of the Environment',
+ `environment_name` varchar(255) NOT NULL COMMENT 'Name of the Environment',
+ `environment_spec` text NOT NULL COMMENT 'Spec of the Environment',
+ `create_by` varchar(32) DEFAULT NULL COMMENT 'create user',
+ `create_time` datetime DEFAULT NULL COMMENT 'create time',
+ `update_by` varchar(32) DEFAULT NULL COMMENT 'last update user',
+ `update_time` datetime DEFAULT NULL COMMENT 'last update time',
+ PRIMARY KEY `id` (`id`),
+ UNIQUE KEY `environment_name` (`environment_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for metric
+-- ----------------------------
+DROP TABLE IF EXISTS `metrics`;
+CREATE TABLE `metrics` (
+ `id` varchar(64) NOT NULL COMMENT 'Id of the Experiment',
+ `key` varchar(190) NOT NULL COMMENT 'Metric key: `String` (limit 190 characters). Part of *Primary Key* for ``metrics`` table.',
+ `value` float NOT NULL COMMENT 'Metric value: `Float`. Defined as *Non-null* in schema.',
+ `worker_index` varchar(32) NOT NULL COMMENT 'Metric worker_index: `String` (limit 32 characters). Part of *Primary Key* for\r\n ``metrics`` table.',
+ `timestamp` bigint(20) NOT NULL COMMENT 'Timestamp recorded for this metric entry: `BigInteger`. Part of *Primary Key* for ``metrics`` table.',
+ `step` bigint(11) NOT NULL COMMENT 'Step recorded for this metric entry: `BigInteger`.',
+ `is_nan` BOOLEAN NOT NULL COMMENT 'True if the value is in fact NaN.',
+ PRIMARY KEY (`id`, `key`, `timestamp`, `worker_index`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Table structure for param
+-- ----------------------------
+DROP TABLE IF EXISTS `params`;
+CREATE TABLE `params` (
+ `id` varchar(64) NOT NULL COMMENT 'Id of the Experiment',
+ `key` varchar(190) NOT NULL COMMENT '`String` (limit 190 characters). Part of *Primary Key* for ``params`` table.',
+ `value` varchar(32) NOT NULL COMMENT '`String` (limit 190 characters). Defined as *Non-null* in schema.',
+ `worker_index` varchar(32) NOT NULL COMMENT '`String` (limit 32 characters). Part of *Primary Key* for\r\n ``metrics`` table.',
+ PRIMARY KEY (`id`, `key`, `worker_index`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+-- ----------------------------
+-- Table structure for experiment_templates
+-- ----------------------------
+DROP TABLE IF EXISTS `experiment_template`;
+CREATE TABLE `experiment_template` (
+ `id` varchar(64) NOT NULL,
+ `experimentTemplate_name` varchar(32) NOT NULL,
+ `experimentTemplate_spec` json DEFAULT NULL,
+ `create_by` varchar(32) DEFAULT NULL,
+ `create_time` datetime NOT NULL,
+ `update_by` varchar(32) DEFAULT NULL,
+ `update_time` datetime NOT NULL,
+ PRIMARY KEY `id` (`id`),
+ UNIQUE KEY `experimentTemplate_name` (`experimentTemplate_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/docs/design/architecture-and-requirements.md b/docs/design/architecture-and-requirements.md
new file mode 100644
index 0000000000000000000000000000000000000000..d41e8795a8ade0c1d9301cf8a687fcde33d3ad44
--- /dev/null
+++ b/docs/design/architecture-and-requirements.md
@@ -0,0 +1,323 @@
+
+
+# Terminology
+
+| Term | Description |
+| -------- | -------- |
+| User | A single data-scientist/data-engineer. User has resource quota, credentials |
+| Team | User belongs to one or more teams, teams have ACLs for artifacts sharing such as notebook content, model, etc. |
+| Admin | Also called SRE, who manages user's quotas, credentials, team, and other components. |
+
+
+# Background
+
+Everybody talks about machine learning today, and lots of companies are trying to leverage machine learning to push the business to the next level. Nowadays, as more and more developers, infrastructure software companies coming to this field, machine learning becomes more and more achievable.
+
+In the last decade, the software industry has built many open source tools for machine learning to solve the pain points:
+
+1. It was not easy to build machine learning algorithms manually, such as logistic regression, GBDT, and many other algorithms:
+ **Answer to that:** Industries have open sourced many algorithm libraries, tools, and even pre-trained models so that data scientists can directly reuse these building blocks to hook up to their data without knowing intricate details inside these algorithms and models.
+
+2. It was not easy to achieve "WYSIWYG, what you see is what you get" from IDEs: not easy to get output, visualization, troubleshooting experiences at the same place.
+ **Answer to that:** Notebooks concept was added to this picture, notebook brought the experiences of interactive coding, sharing, visualization, debugging under the same user interface. There're popular open-source notebooks like Apache Zeppelin/Jupyter.
+
+3. It was not easy to manage dependencies: ML applications can run on one machine is hard to deploy on another machine because it has lots of libraries dependencies.
+ **Answer to that:** Containerization becomes popular and a standard to packaging dependencies to make it easier to "build once, run anywhere".
+
+4. Fragmented tools, libraries were hard for ML engineers to learn. Experiences learned in one company are not naturally migratable to another company.
+ **Answer to that:** A few dominant open-source frameworks reduced the overhead of learning too many different frameworks, concepts. Data-scientist can learn a few libraries such as Tensorflow/PyTorch, and a few high-level wrappers like Keras will be able to create your machine learning application from other open-source building blocks.
+
+5. Similarly, models built by one library (such as libsvm) were hard to be integrated into machine learning pipeline since there's no standard format.
+ **Answer to that:** Industry has built successful open-source standard machine learning frameworks such as Tensorflow/PyTorch/Keras so their format can be easily shared across. And efforts to build an even more general model format such as ONNX.
+
+6. It was hard to build a data pipeline that flows/transform data from a raw data source to whatever required by ML applications.
+ **Answer to that:** Open source big data industry plays an important role in providing, simplify, unify processes and building blocks for data flows, transformations, etc.
+
+The machine learning industry is moving on the right track to solve major roadblocks. So what are the pain points now for companies which have machine learning needs? What can we help here? To answer this question, let's look at machine learning workflow first.
+
+## Machine Learning Workflows & Pain points
+
+```
+1) From different data sources such as edge, clickstream, logs, etc.
+ => Land to data lakes
+
+2) From data lake, data transformation:
+ => Data transformations: Cleanup, remove invalid rows/columns,
+ select columns, sampling, split train/test
+ data-set, join table, etc.
+ => Data prepared for training.
+
+3) From prepared data:
+ => Training, model hyper-parameter tuning, cross-validation, etc.
+ => Models saved to storage.
+
+4) From saved models:
+ => Model assurance, deployment, A/B testing, etc.
+ => Model deployed for online serving or offline scoring.
+```
+
+Typically data scientists responsible for item 2)-4), 1) typically handled by a different team (called Data Engineering team in many companies, some Data Engineering team also responsible for part of data transformation)
+
+### Pain \#1 Complex workflow/steps from raw data to model, different tools needed by different steps, hard to make changes to workflow, and not error-proof
+
+It is a complex workflow from raw data to usable models, after talking to many different data scientists, we have learned that a typical procedure to train a new model and push to production can take months to 1-2 years.
+
+It is also a wide skill set required by this workflow. For example, data transformation needs tools like Spark/Hive for large scale and tools like Pandas for a small scale. And model training needs to be switched between XGBoost, Tensorflow, Keras, PyTorch. Building a data pipeline requires Apache Airflow or Oozie.
+
+Yes, there are great, standardized open-source tools built for many of such purposes. But how about changes need to be made for a particular part of the data pipeline? How about adding a few columns to the training data for experiments? How about training models, and push models to validation, A/B testing before rolling to production? All these steps need jumping between different tools, UIs, and very hard to make changes, and it is not error-proof during these procedures.
+
+### Pain \#2 Dependencies of underlying resource management platform
+
+To make jobs/services required by a machine learning platform to be able to run, we need an underlying resource management platform. There're some choices of resource management platform, and they have distinct advantages and disadvantages.
+
+For example, there're many machine learning platform built on top of K8s. It is relatively easy to get a K8s from a cloud vendor, easy to orchestrate machine learning required services/daemons run on K8s. However, K8s doesn't offer good support jobs like Spark/Flink/Hive. So if your company has Spark/Flink/Hive running on YARN, there're gaps and a significant amount of work to move required jobs from YARN to K8s. Maintaining a separate K8s cluster is also overhead to Hadoop-based data infrastructure.
+
+Similarly, if your company's data pipelines are mostly built on top of cloud resources and SaaS offerings, asking you to install a separate YARN cluster to run a new machine learning platform doesn't make a lot of sense.
+
+### Pain \#3 Data scientist are forced to interact with lower-level platform components
+
+In addition to the above pain, we do see Data Scientists are forced to learn underlying platform knowledge to be able to build a real-world machine learning workflow.
+
+For most of the data scientists we talked with, they're experts of ML algorithms/libraries, feature engineering, etc. They're also most familiar with Python, R, and some of them understand Spark, Hive, etc.
+
+If they're asked to do interactions with lower-level components like fine-tuning a Spark job's performance; or troubleshooting job failed to launch because of resource constraints; or write a K8s/YARN job spec and mount volumes, set networks properly. They will scratch their heads and typically cannot perform these operations efficiently.
+
+### Pain \#4 Comply with data security/governance requirements
+
+TODO: Add more details.
+
+### Pain \#5 No good way to reduce routine ML code development
+
+After the data is prepared, the data scientist needs to do several routine tasks to build the ML pipeline. To get a sense of the existing the data set, it usually needs a split of the data set, the statistics of data set. These tasks have a common duplicate part of code, which reduces the efficiency of data scientists.
+
+An abstraction layer/framework to help the developer to boost ML pipeline development could be valuable. It's better than the developer only needs to fill callback function to focus on their key logic.
+
+# Submarine
+
+## Overview
+
+### A little bit history
+
+Initially, Submarine is built to solve problems of running deep learning jobs like Tensorflow/PyTorch on Apache Hadoop YARN, allows admin to monitor launched deep learning jobs, and manage generated models.
+
+It was part of YARN initially, and code resides under `hadoop-yarn-applications`. Later, the community decided to convert it to be a subproject within Hadoop (Sibling project of YARN, HDFS, etc.) because we want to support other resource management platforms like K8s. And finally, we're reconsidering Submarine's charter, and the Hadoop community voted that it is the time to moved Submarine to a separate Apache TLP.
+
+### Why Submarine?
+
+`ONE PLATFORM`
+
+Submarine is the ONE PLATFORM to allow Data Scientists to create end-to-end machine learning workflow. `ONE PLATFORM` means it supports Data Scientists and data engineers to finish their jobs on the same platform without frequently switching their toolsets. From dataset exploring data pipeline creation, model training, and tuning, and push model to production. All these steps can be completed within the `ONE PLATFORM`.
+
+`Resource Management Independent`
+
+It is also designed to be resource management independent, no matter if you have Apache Hadoop YARN, K8s, or just a container service, you will be able to run Submarine on top it.
+
+
+## Requirements and non-requirements
+
+### Notebook
+
+1) Users should be able to create, edit, delete a notebook. (P0)
+2) Notebooks can be persisted to storage and can be recovered if failure happens. (P0)
+3) Users can trace back to history versions of a notebook. (P1)
+4) Notebooks can be shared with different users. (P1)
+5) Users can define a list of parameters of a notebook (looks like parameters of the notebook's main function) to allow executing a notebook like a job. (P1)
+6) Different users can collaborate on the same notebook at the same time. (P2)
+
+A running notebook instance is called notebook session (or session for short).
+
+### Experiment
+
+Experiments of Submarine is an offline task. It could be a shell command, a Python command, a Spark job, a SQL query, or even a workflow.
+
+The primary purposes of experiments under Submarine's context is to do training tasks, offline scoring, etc. However, experiment can be generalized to do other tasks as well.
+
+Major requirement of experiment:
+
+1) Experiments can be submitted from UI/CLI/SDK.
+2) Experiments can be monitored/managed from UI/CLI/SDK.
+3) Experiments should not bind to one resource management platform (K8s/YARN).
+
+#### Type of experiments
+
+
+
+There're two types of experiments:
+`Adhoc experiments`: which includes a Python/R/notebook, or even an adhoc Tensorflow/PyTorch task, etc.
+
+`Predefined experiment library`: This is specialized experiments, which including developed libraries such as CTR, BERT, etc. Users are only required to specify a few parameters such as input, output, hyper parameters, etc. Instead of worrying about where's training script/dependencies located.
+
+#### Adhoc experiment
+
+Requirements:
+
+- Allow run adhoc scripts.
+- Allow model engineer, data scientist to run Tensorflow/Pytorch programs on YARN/K8s/Container-cloud.
+- Allow jobs easy access data/models in HDFS/s3, etc.
+- Support run distributed Tensorflow/Pytorch jobs with simple configs.
+- Support run user-specified Docker images.
+- Support specify GPU and other resources.
+
+#### Predefined experiment library
+
+Here's an example of predefined experiment library to train deepfm model:
+
+```
+{
+ "input": {
+ "train_data": ["hdfs:///user/submarine/data/tr.libsvm"],
+ "valid_data": ["hdfs:///user/submarine/data/va.libsvm"],
+ "test_data": ["hdfs:///user/submarine/data/te.libsvm"],
+ "type": "libsvm"
+ },
+ "output": {
+ "save_model_dir": "hdfs:///user/submarine/deepfm",
+ "metric": "auc"
+ },
+ "training": {
+ "batch_size" : 512,
+ "field_size": 39,
+ "num_epochs": 3,
+ "feature_size": 117581,
+ ...
+ }
+}
+```
+
+Predefined experiment libraries can be shared across users on the same platform, users can also add new or modified predefined experiment library via UI/REST API.
+
+We will also model AutoML, auto hyper-parameter tuning to predefined experiment library.
+
+#### Pipeline
+
+Pipeline is a special kind of experiment:
+
+- A pipeline is a DAG of experiments.
+- Can be also treated as a special kind of experiment.
+- Users can submit/terminate a pipeline.
+- Pipeline can be created/submitted via UI/API.
+
+### Environment Profiles
+
+Environment profiles (or environment for short) defines a set of libraries and when Docker is being used, a Docker image in order to run an experiment or a notebook.
+
+Docker or VM image (such as AMI: Amazon Machine Images) defines the base layer of the environment.
+
+On top of that, users can define a set of libraries (such as Python/R) to install.
+
+Users can save different environment configs which can be also shared across the platform. Environment profiles can be used to run a notebook (e.g. by choosing different kernel from Jupyter), or an experiment. Predefined experiment library includes what environment to use so users don't have to choose which environment to use.
+
+Environments can be added/listed/deleted/selected through CLI/SDK.
+
+### Model
+
+#### Model management
+
+- Model artifacts are generated by experiments or notebook.
+- A model consists of artifacts from one or multiple files.
+- Users can choose to save, tag, version a produced model.
+- Once The Model is saved, Users can do the online model serving or offline scoring of the model.
+
+#### Model serving
+
+After model saved, users can specify a serving script, a model and create a web service to serve the model.
+
+We call the web service to "endpoint". Users can manage (add/stop) model serving endpoints via CLI/API/UI.
+
+### Metrics for training job and model
+
+Submarine-SDK provides tracking/metrics APIs, which allows developers to add tracking/metrics and view tracking/metrics from Submarine Workbench UI.
+
+### Deployment
+
+Submarine Services (See architecture overview below) should be deployed easily on-prem / on-cloud. Since there're more and more public cloud offering for compute/storage management on cloud, we need to support deploy Submarine compute-related workloads (such as notebook session, experiments, etc.) to cloud-managed clusters.
+
+This also include Submarine may need to take input parameters from customers and create/manage clusters if needed. It is also a common requirement to use hybrid of on-prem/on-cloud clusters.
+
+### Security / Access Control / User Management / Quota Management
+
+There're 4 kinds of objects need access-control:
+
+- Assets belong to Submarine system, which includes notebook, experiments and results, models, predefined experiment libraries, environment profiles.
+- Data security. (Who owns what data, and what data can be accessed by each users).
+- User credentials. (Such as LDAP).
+- Other security, such as Git repo access, etc.
+
+For the data security / user credentials / other security, it will be delegated to 3rd libraries such as Apache Ranger, IAM roles, etc.
+
+Assets belong to Submarine system will be handled by Submarine itself.
+
+Here're operations which Submarine admin can do for users / teams which can be used to access Submarine's assets.
+
+**Operations for admins**
+
+- Admin uses "User Management System" to onboard new users, upload user credentials, assign resource quotas, etc.
+- Admins can create new users, new teams, update user/team mappings. Or remove users/teams.
+- Admin can set resource quotas (if different from system default), permissions, upload/update necessary credentials (like Kerberos keytab) of a user.
+- A DE/DS can also be an admin if the DE/DS has admin access. (Like a privileged user). This will be useful when a cluster is exclusively shared by a user or only shared by a small team.
+- `Resource Quota Management System` helps admin to manage resources quotas of teams, organizations. Resources can be machine resources like CPU/Memory/Disk, etc. It can also include non-machine resources like $$-based budgets.
+
+### Dataset
+
+There's also need to tag dataset which will be used for training and shared across the platform by different users.
+
+Like mentioned above, access to the actual data will be handled by 3rd party system like Apache Ranger / Hive Metastore which is out of the Submarine's scope.
+
+## Architecture Overview
+
+### Architecture Diagram
+
+```
+ +-----------------------------------------------------------------+
+ | Submarine UI / CLI / REST API / SDK |
+ | Mini-Submarine |
+ +-----------------------------------------------------------------+
+
+ +--------------------Submarine Server-----------------------------+
+ | +---------+ +---------+ +----------+ +----------+ +------------+|
+ | |Data set | |Notebooks| |Experiment| |Models | |Servings ||
+ | +---------+ +---------+ +----------+ +----------+ +------------+|
+ |-----------------------------------------------------------------|
+ | |
+ | +-----------------+ +-----------------+ +---------------------+ |
+ | |Experiment | |Compute Resource | |Other Management | |
+ | |Manager | | Manager | |Services | |
+ | +-----------------+ +-----------------+ +---------------------+ |
+ | Spark, template YARN/K8s/Docker |
+ | TF, PyTorch, pipeline |
+ | |
+ + +-----------------+ +
+ | |Submarine Meta | |
+ | | Store | |
+ | +-----------------+ |
+ | |
+ +-----------------------------------------------------------------+
+
+ (You can use http://stable.ascii-flow.appspot.com/#Draw
+ to draw such diagrams)
+```
+
+`Compute Resource Manager` Helps to manage compute resources on-prem/on-cloud, this module can also handle cluster creation / management, etc.
+
+`Experiment Manager` Work with "Compute Resource Manager" to submit different kinds of workloads such as (distributed) Tensorflow / Pytorch, etc.
+
+`Submarine SDK` provides Java/Python/REST API to allow DS or other engineers to integrate into Submarine services. It also includes a `mini-submarine` component that launches Submarine components from a single Docker container (or a VM image).
+
+Details of Submarine Server design can be found at [submarine-server-design](./submarine-server/architecture.md).
+
+# References
+
+
diff --git a/docs/design/environments-implementation.md b/docs/design/environments-implementation.md
new file mode 100644
index 0000000000000000000000000000000000000000..14e51c8b74f34cdc59a6a016414952e0547da60c
--- /dev/null
+++ b/docs/design/environments-implementation.md
@@ -0,0 +1,194 @@
+
+
+# Overview
+
+Environment profiles (or environment for short) defines a set of libraries and when Docker is being used, a Docker image in order to run an experiment or a notebook.
+
+Docker and/or VM-image (such as, VirtualBox/VMWare images, Amazon Machine Images - AMI, Or custom image of Azure VM) defines the base layer of the environment. Please note that VM-image is different from VM instance type,
+
+On top of that, users can define a set of libraries (such as Python/R) to install, we call it kernel.
+
+**Example of Environment**
+
+```
+
+ +-------------------+
+ |+-----------------+|
+ || Python=3.7 ||
+ || Tensorflow=2.0 ||
+ |+---Exp Dependency+|
+ |+-----------------+|
+ ||OS=Ubuntu16.04 ||
+ ||CUDA=10.2 ||
+ ||GPU_Driver=375.. ||
+ |+---Base Library--+|
+ +-------------------+
+```
+
+As you can see, There're base libraries, such as what OS, CUDA version, GPU driver, etc. They can be achieved by specifying a VM-image / Docker image.
+
+On top of that, user can bring their dependencies, such as different version of Python, Tensorflow, Pandas, etc.
+
+**How users use environment?**
+
+Users can save different environment configs which can be also shared across the platform. Environment profiles can be used to run a notebook (e.g. by choosing different kernel from Jupyter), or an experiment. Predefined experiment library includes what environment to use so users don't have to choose which environment to use.
+
+```
+
+ +-------------------+
+ |+-----------------+| +------------+
+ || Python=3.7 || |User1 |
+ || Tensorflow=2.0 || +------------+
+ |+---Kernel -------+| +------------+
+ |+-----------------+|<----+ |User2 |
+ ||OS=Ubuntu16.04 || + +------------+
+ ||CUDA=10.2 || | +------------+
+ ||GPU_Driver=375.. || | |User3 |
+ |+---Base Library--+| | +------------+
+ +-----Default-Env---+ |
+ |
+ |
+ +-------------------+ |
+ |+-----------------+| |
+ || Python=3.3 || |
+ || Tensorflow=2.0 || |
+ |+---kernel--------+| |
+ |+-----------------+| |
+ ||OS=Ubuntu16.04 || |
+ ||CUDA=10.3 ||<----+
+ ||GPU_Driver=375.. ||
+ |+---Base Library--+|
+ +-----My-Customized-+
+```
+
+There're two environments in the above graph, "Default-Env" and "My-Customized", which can have different combinations of libraries for different experiments/notebooks. Users can choose different environments for different experiments as they want.
+
+Environments can be added/listed/deleted/selected through CLI/SDK/UI.
+
+# Implementation
+
+## Environment API definition
+
+Let look at what object definition looks like to define an environment, API of environment looks like:
+
+```
+ name: "my_submarine_env",
+ vm-image: "...",
+ docker-image: "...",
+ kernel:
+