diff --git a/flink-core/src/main/java/org/apache/flink/configuration/ConfigConstants.java b/flink-core/src/main/java/org/apache/flink/configuration/ConfigConstants.java
index fb5a7605acd66..da3cce473b02c 100644
--- a/flink-core/src/main/java/org/apache/flink/configuration/ConfigConstants.java
+++ b/flink-core/src/main/java/org/apache/flink/configuration/ConfigConstants.java
@@ -439,6 +439,11 @@ public final class ConfigConstants {
// ------------------------ Mesos Configuration ------------------------
+ /**
+ * The initial number of Mesos tasks to allocate.
+ */
+ public static final String MESOS_INITIAL_TASKS = "mesos.initial-tasks";
+
/**
* The maximum number of failed Mesos tasks before entirely stopping
* the Mesos session / job on Mesos.
@@ -484,6 +489,8 @@ public final class ConfigConstants {
public static final String MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET = "mesos.resourcemanager.framework.secret";
+ public static final String MESOS_RESOURCEMANAGER_FRAMEWORK_USER = "mesos.resourcemanager.framework.user";
+
/**
* The cpus to acquire from Mesos.
*
@@ -1158,6 +1165,8 @@ public final class ConfigConstants {
public static final String DEFAULT_MESOS_RESOURCEMANAGER_FRAMEWORK_ROLE = "*";
+ public static final String DEFAULT_MESOS_RESOURCEMANAGER_FRAMEWORK_USER = "";
+
// ------------------------ File System Behavior ------------------------
/**
@@ -1372,6 +1381,12 @@ public final class ConfigConstants {
/** The environment variable name which contains the location of the lib folder */
public static final String ENV_FLINK_LIB_DIR = "FLINK_LIB_DIR";
+ /** The environment variable name which contains the location of the bin directory */
+ public static final String ENV_FLINK_BIN_DIR = "FLINK_BIN_DIR";
+
+ /** The environment variable name which contains the Flink installation root directory */
+ public static final String ENV_FLINK_HOME_DIR = "FLINK_HOME";
+
// -------------------------------- Security -------------------------------
/**
diff --git a/flink-core/src/main/java/org/apache/flink/configuration/GlobalConfiguration.java b/flink-core/src/main/java/org/apache/flink/configuration/GlobalConfiguration.java
index 8d550d7918a06..62668295ee71d 100644
--- a/flink-core/src/main/java/org/apache/flink/configuration/GlobalConfiguration.java
+++ b/flink-core/src/main/java/org/apache/flink/configuration/GlobalConfiguration.java
@@ -39,12 +39,31 @@ public final class GlobalConfiguration {
public static final String FLINK_CONF_FILENAME = "flink-conf.yaml";
+
// --------------------------------------------------------------------------------------------
private GlobalConfiguration() {}
// --------------------------------------------------------------------------------------------
+ private static Configuration dynamicProperties = null;
+
+ /**
+ * Set the process-wide dynamic properties to be merged with the loaded configuration.
+ */
+ public static void setDynamicProperties(Configuration dynamicProperties) {
+ GlobalConfiguration.dynamicProperties = new Configuration(dynamicProperties);
+ }
+
+ /**
+ * Get the dynamic properties.
+ */
+ public static Configuration getDynamicProperties() {
+ return GlobalConfiguration.dynamicProperties;
+ }
+
+ // --------------------------------------------------------------------------------------------
+
/**
* Loads the global configuration from the environment. Fails if an error occurs during loading. Returns an
* empty configuration object if the environment variable is not set. In production this variable is set but
@@ -90,7 +109,13 @@ public static Configuration loadConfiguration(final String configDir) {
"' (" + confDirFile.getAbsolutePath() + ") does not exist.");
}
- return loadYAMLResource(yamlConfigFile);
+ Configuration conf = loadYAMLResource(yamlConfigFile);
+
+ if(dynamicProperties != null) {
+ conf.addAll(dynamicProperties);
+ }
+
+ return conf;
}
/**
diff --git a/flink-dist/src/main/assemblies/bin.xml b/flink-dist/src/main/assemblies/bin.xml
index b4291d3d49b40..901cac9100090 100644
--- a/flink-dist/src/main/assemblies/bin.xml
+++ b/flink-dist/src/main/assemblies/bin.xml
@@ -82,6 +82,12 @@ under the License.
bin0755
+
+
+ src/main/flink-bin/mesos-bin
+ bin
+ 0755
+
diff --git a/flink-dist/src/main/flink-bin/mesos-bin/mesos-appmaster.sh b/flink-dist/src/main/flink-bin/mesos-bin/mesos-appmaster.sh
new file mode 100755
index 0000000000000..d65c6b0b65642
--- /dev/null
+++ b/flink-dist/src/main/flink-bin/mesos-bin/mesos-appmaster.sh
@@ -0,0 +1,51 @@
+#!/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.
+################################################################################
+
+bin=`dirname "$0"`
+bin=`cd "$bin"; pwd`
+
+# get Flink config
+. "$bin"/config.sh
+
+# auxilliary function to construct a lightweight classpath for the
+# Flink AppMaster
+constructAppMasterClassPath() {
+
+ while read -d '' -r jarfile ; do
+ if [[ $CC_CLASSPATH = "" ]]; then
+ CC_CLASSPATH="$jarfile";
+ else
+ CC_CLASSPATH="$CC_CLASSPATH":"$jarfile"
+ fi
+ done < <(find "$FLINK_LIB_DIR" ! -type d -name '*.jar' -print0)
+
+ echo $CC_CLASSPATH:$INTERNAL_HADOOP_CLASSPATHS
+}
+
+CC_CLASSPATH=`manglePathList $(constructAppMasterClassPath)`
+
+log=flink-appmaster.log
+log_setting="-Dlog.file="$log" -Dlog4j.configuration=file:"$FLINK_CONF_DIR"/log4j.properties -Dlogback.configurationFile=file:"$FLINK_CONF_DIR"/logback.xml"
+
+export FLINK_CONF_DIR
+export FLINK_BIN_DIR
+export FLINK_LIB_DIR
+
+$JAVA_RUN $JVM_ARGS -classpath "$CC_CLASSPATH" $log_setting org.apache.flink.mesos.runtime.clusterframework.MesosApplicationMasterRunner "$@"
+
diff --git a/flink-dist/src/main/flink-bin/mesos-bin/mesos-taskmanager.sh b/flink-dist/src/main/flink-bin/mesos-bin/mesos-taskmanager.sh
new file mode 100755
index 0000000000000..ff03abd5f806f
--- /dev/null
+++ b/flink-dist/src/main/flink-bin/mesos-bin/mesos-taskmanager.sh
@@ -0,0 +1,60 @@
+#!/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.
+################################################################################
+
+bin=`dirname "$0"`
+bin=`cd "$bin"; pwd`
+
+# get Flink config
+. "$bin"/config.sh
+
+# auxilliary function to construct a lightweight classpath for the
+# Flink TaskManager
+constructTaskManagerClassPath() {
+
+ while read -d '' -r jarfile ; do
+ if [[ $CC_CLASSPATH = "" ]]; then
+ CC_CLASSPATH="$jarfile";
+ else
+ CC_CLASSPATH="$CC_CLASSPATH":"$jarfile"
+ fi
+ done < <(find "$FLINK_LIB_DIR" ! -type d -name '*.jar' -print0)
+
+ echo $CC_CLASSPATH:$INTERNAL_HADOOP_CLASSPATHS
+}
+
+CC_CLASSPATH=`manglePathList $(constructTaskManagerClassPath)`
+
+log=flink-taskmanager.log
+log_setting="-Dlog.file="$log" -Dlog4j.configuration=file:"$FLINK_CONF_DIR"/log4j.properties -Dlogback.configurationFile=file:"$FLINK_CONF_DIR"/logback.xml"
+
+# Add precomputed memory JVM options
+if [ -z "${FLINK_ENV_JAVA_OPTS_MEM}" ]; then
+ FLINK_ENV_JAVA_OPTS_MEM=""
+fi
+export FLINK_ENV_JAVA_OPTS="${FLINK_ENV_JAVA_OPTS} ${FLINK_ENV_JAVA_OPTS_MEM}"
+
+# Add TaskManager-specific JVM options
+export FLINK_ENV_JAVA_OPTS="${FLINK_ENV_JAVA_OPTS} ${FLINK_ENV_JAVA_OPTS_TM}"
+
+export FLINK_CONF_DIR
+export FLINK_BIN_DIR
+export FLINK_LIB_DIR
+
+$JAVA_RUN $JVM_ARGS ${FLINK_ENV_JAVA_OPTS} -classpath "$CC_CLASSPATH" $log_setting org.apache.flink.mesos.runtime.clusterframework.MesosTaskManager "$@"
+
diff --git a/flink-mesos/pom.xml b/flink-mesos/pom.xml
index a6edc0b648825..8814762b9c643 100644
--- a/flink-mesos/pom.xml
+++ b/flink-mesos/pom.xml
@@ -32,7 +32,7 @@ under the License.
jar
- 0.27.1
+ 1.0.1
@@ -68,6 +68,13 @@ under the License.
com.typesafe.akkaakka-remote_${scala.binary.version}
+
+
+
+ com.google.protobuf
+ protobuf-java
+
+
@@ -253,15 +260,21 @@ under the License.
shade
+ trueorg.apache.flink:flink-shaded-curator-recipes
+ com.google.protobuf:*
-
+ org.apache.curator
- org.apache.flink.shaded.org.apache.curator
+ org.apache.flink.mesos.shaded.org.apache.curator
+
+
+ com.google.protobuf
+ org.apache.flink.mesos.shaded.com.google.protobuf
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/Utils.java b/flink-mesos/src/main/java/org/apache/flink/mesos/Utils.java
index 173ae334ff553..7787e4055f2e3 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/Utils.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/Utils.java
@@ -18,7 +18,10 @@
package org.apache.flink.mesos;
+import org.apache.flink.mesos.util.MesosArtifactResolver;
+import org.apache.flink.runtime.clusterframework.ContainerSpecification;
import org.apache.mesos.Protos;
+import scala.Option;
import java.net.URL;
import java.util.Arrays;
@@ -45,6 +48,24 @@ public static Protos.CommandInfo.URI uri(URL url, boolean cacheable) {
.build();
}
+ /**
+ * Construct a Mesos URI.
+ */
+ public static Protos.CommandInfo.URI uri(MesosArtifactResolver resolver, ContainerSpecification.Artifact artifact) {
+ Option url = resolver.resolve(artifact.dest);
+ if(url.isEmpty()) {
+ throw new IllegalArgumentException("Unresolvable artifact: " + artifact.dest);
+ }
+
+ return Protos.CommandInfo.URI.newBuilder()
+ .setValue(url.get().toExternalForm())
+ .setOutputFile(artifact.dest.toString())
+ .setExtract(artifact.extract)
+ .setCache(artifact.cachable)
+ .setExecutable(artifact.executable)
+ .build();
+ }
+
/**
* Construct a scalar resource value.
*/
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/LaunchableMesosWorker.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/LaunchableMesosWorker.java
index 5f940b53924c1..a7438ad019939 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/LaunchableMesosWorker.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/LaunchableMesosWorker.java
@@ -23,8 +23,11 @@
import com.netflix.fenzo.TaskRequest;
import com.netflix.fenzo.VMTaskFitnessCalculator;
import org.apache.flink.configuration.Configuration;
-import org.apache.flink.mesos.cli.FlinkMesosSessionCli;
+import org.apache.flink.mesos.Utils;
import org.apache.flink.mesos.scheduler.LaunchableTask;
+import org.apache.flink.mesos.util.MesosArtifactResolver;
+import org.apache.flink.runtime.clusterframework.ContaineredTaskManagerParameters;
+import org.apache.flink.runtime.clusterframework.ContainerSpecification;
import org.apache.mesos.Protos;
import java.util.Collections;
@@ -38,7 +41,10 @@
import static org.apache.flink.mesos.Utils.scalar;
/**
- * Specifies how to launch a Mesos worker.
+ * Implements the launch of a Mesos worker.
+ *
+ * Translates the abstract {@link ContainerSpecification} into a concrete
+ * Mesos-specific {@link org.apache.mesos.Protos.TaskInfo}.
*/
public class LaunchableMesosWorker implements LaunchableTask {
@@ -49,20 +55,24 @@ public class LaunchableMesosWorker implements LaunchableTask {
"taskmanager.rpc.port",
"taskmanager.data.port" };
+ private final MesosArtifactResolver resolver;
+ private final ContainerSpecification containerSpec;
private final MesosTaskManagerParameters params;
- private final Protos.TaskInfo.Builder template;
private final Protos.TaskID taskID;
private final Request taskRequest;
/**
* Construct a launchable Mesos worker.
* @param params the TM parameters such as memory, cpu to acquire.
- * @param template a template for the TaskInfo to be constructed at launch time.
+ * @param containerSpec an abstract container specification for launch time.
* @param taskID the taskID for this worker.
*/
- public LaunchableMesosWorker(MesosTaskManagerParameters params, Protos.TaskInfo.Builder template, Protos.TaskID taskID) {
+ public LaunchableMesosWorker(
+ MesosArtifactResolver resolver, MesosTaskManagerParameters params,
+ ContainerSpecification containerSpec, Protos.TaskID taskID) {
+ this.resolver = resolver;
this.params = params;
- this.template = template;
+ this.containerSpec = containerSpec;
this.taskID = taskID;
this.taskRequest = new Request();
}
@@ -157,17 +167,25 @@ public String toString() {
@Override
public Protos.TaskInfo launch(Protos.SlaveID slaveId, TaskAssignmentResult assignment) {
+ ContaineredTaskManagerParameters tmParams = params.containeredParameters();
+
final Configuration dynamicProperties = new Configuration();
- // specialize the TaskInfo template with assigned resources, environment variables, etc
- final Protos.TaskInfo.Builder taskInfo = template
- .clone()
+ // incorporate the dynamic properties set by the template
+ dynamicProperties.addAll(containerSpec.getDynamicConfiguration());
+
+ // build a TaskInfo with assigned resources, environment variables, etc
+ final Protos.TaskInfo.Builder taskInfo = Protos.TaskInfo.newBuilder()
.setSlaveId(slaveId)
.setTaskId(taskID)
.setName(taskID.getValue())
.addResources(scalar("cpus", assignment.getRequest().getCPUs()))
.addResources(scalar("mem", assignment.getRequest().getMemory()));
+ final Protos.CommandInfo.Builder cmd = taskInfo.getCommandBuilder();
+ final Protos.Environment.Builder env = cmd.getEnvironmentBuilder();
+ final StringBuilder jvmArgs = new StringBuilder();
+
// use the assigned ports for the TM
if (assignment.getAssignedPorts().size() < TM_PORT_KEYS.length) {
throw new IllegalArgumentException("unsufficient # of ports assigned");
@@ -179,17 +197,38 @@ public Protos.TaskInfo launch(Protos.SlaveID slaveId, TaskAssignmentResult assig
dynamicProperties.setInteger(key, port);
}
- // finalize environment variables
- final Protos.Environment.Builder environmentBuilder = taskInfo.getCommandBuilder().getEnvironmentBuilder();
+ // ship additional files
+ for(ContainerSpecification.Artifact artifact : containerSpec.getArtifacts()) {
+ cmd.addUris(Utils.uri(resolver, artifact));
+ }
+
+ // propagate environment variables
+ for (Map.Entry entry : params.containeredParameters().taskManagerEnv().entrySet()) {
+ env.addVariables(variable(entry.getKey(), entry.getValue()));
+ }
+ for (Map.Entry entry : containerSpec.getEnvironmentVariables().entrySet()) {
+ env.addVariables(variable(entry.getKey(), entry.getValue()));
+ }
// propagate the Mesos task ID to the TM
- environmentBuilder
- .addVariables(variable(MesosConfigKeys.ENV_FLINK_CONTAINER_ID, taskInfo.getTaskId().getValue()));
+ env.addVariables(variable(MesosConfigKeys.ENV_FLINK_CONTAINER_ID, taskInfo.getTaskId().getValue()));
+
+ // finalize the memory parameters
+ jvmArgs.append(" -Xms").append(tmParams.taskManagerHeapSizeMB()).append("m");
+ jvmArgs.append(" -Xmx").append(tmParams.taskManagerHeapSizeMB()).append("m");
+ jvmArgs.append(" -XX:MaxDirectMemorySize=").append(tmParams.taskManagerDirectMemoryLimitMB()).append("m");
+
+ // pass dynamic system properties
+ jvmArgs.append(' ').append(
+ ContainerSpecification.formatSystemProperties(containerSpec.getSystemProperties()));
+
+ // finalize JVM args
+ env.addVariables(variable(MesosConfigKeys.ENV_JVM_ARGS, jvmArgs.toString()));
- // propagate the dynamic configuration properties to the TM
- String dynamicPropertiesEncoded = FlinkMesosSessionCli.encodeDynamicProperties(dynamicProperties);
- environmentBuilder
- .addVariables(variable(MesosConfigKeys.ENV_DYNAMIC_PROPERTIES, dynamicPropertiesEncoded));
+ // build the launch command w/ dynamic application properties
+ StringBuilder launchCommand = new StringBuilder("$FLINK_HOME/bin/mesos-taskmanager.sh ");
+ launchCommand.append(ContainerSpecification.formatSystemProperties(dynamicProperties));
+ cmd.setValue(launchCommand.toString());
return taskInfo.build();
}
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosApplicationMasterRunner.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosApplicationMasterRunner.java
index 5ec39c2ab8d0d..a5c88c454e905 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosApplicationMasterRunner.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosApplicationMasterRunner.java
@@ -23,12 +23,17 @@
import akka.actor.Address;
import akka.actor.Props;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
import org.apache.curator.framework.CuratorFramework;
+import org.apache.flink.api.java.hadoop.mapred.utils.HadoopUtils;
import org.apache.flink.configuration.ConfigConstants;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.GlobalConfiguration;
import org.apache.flink.configuration.IllegalConfigurationException;
-import org.apache.flink.mesos.cli.FlinkMesosSessionCli;
+import org.apache.flink.core.fs.FileSystem;
import org.apache.flink.mesos.runtime.clusterframework.store.MesosWorkerStore;
import org.apache.flink.mesos.runtime.clusterframework.store.StandaloneMesosWorkerStore;
import org.apache.flink.mesos.runtime.clusterframework.store.ZooKeeperMesosWorkerStore;
@@ -37,40 +42,40 @@
import org.apache.flink.mesos.util.ZooKeeperUtils;
import org.apache.flink.runtime.akka.AkkaUtils;
import org.apache.flink.runtime.clusterframework.BootstrapTools;
-import org.apache.flink.runtime.clusterframework.ContaineredTaskManagerParameters;
+import org.apache.flink.runtime.clusterframework.overlays.CompositeContainerOverlay;
+import org.apache.flink.runtime.clusterframework.ContainerSpecification;
+import org.apache.flink.runtime.clusterframework.overlays.FlinkDistributionOverlay;
+import org.apache.flink.runtime.clusterframework.overlays.HadoopConfOverlay;
+import org.apache.flink.runtime.clusterframework.overlays.HadoopUserOverlay;
+import org.apache.flink.runtime.clusterframework.overlays.KeytabOverlay;
+import org.apache.flink.runtime.clusterframework.overlays.Krb5ConfOverlay;
+import org.apache.flink.runtime.clusterframework.overlays.SSLStoreOverlay;
import org.apache.flink.runtime.jobmanager.HighAvailabilityMode;
import org.apache.flink.runtime.jobmanager.JobManager;
import org.apache.flink.runtime.jobmanager.MemoryArchivist;
import org.apache.flink.runtime.leaderretrieval.LeaderRetrievalService;
import org.apache.flink.runtime.process.ProcessReaper;
-import org.apache.flink.runtime.taskmanager.TaskManager;
+import org.apache.flink.runtime.security.SecurityContext;
import org.apache.flink.runtime.util.EnvironmentInformation;
import org.apache.flink.runtime.util.JvmShutdownSafeguard;
import org.apache.flink.runtime.util.LeaderRetrievalUtils;
import org.apache.flink.runtime.util.SignalHandler;
import org.apache.flink.runtime.webmonitor.WebMonitor;
-import org.apache.hadoop.security.UserGroupInformation;
-
import org.apache.mesos.Protos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import scala.Option;
import scala.concurrent.duration.Duration;
import scala.concurrent.duration.FiniteDuration;
-import java.io.File;
+import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
-import java.security.PrivilegedAction;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
-import static org.apache.flink.mesos.Utils.uri;
-import static org.apache.flink.mesos.Utils.variable;
-
import static org.apache.flink.util.Preconditions.checkState;
/**
@@ -98,6 +103,18 @@ public class MesosApplicationMasterRunner {
/** The exit code returned if the process exits because a critical actor died */
private static final int ACTOR_DIED_EXIT_CODE = 32;
+ // ------------------------------------------------------------------------
+ // Command-line options
+ // ------------------------------------------------------------------------
+
+ private static final Options ALL_OPTIONS;
+
+ static {
+ ALL_OPTIONS =
+ new Options()
+ .addOption(BootstrapTools.newDynamicPropertiesOption());
+ }
+
// ------------------------------------------------------------------------
// Program entry point
// ------------------------------------------------------------------------
@@ -119,30 +136,44 @@ public static void main(String[] args) {
/**
* The instance entry point for the Mesos AppMaster. Obtains user group
- * information and calls the main work method {@link #runPrivileged()} as a
+ * information and calls the main work method {@link #runPrivileged} as a
* privileged action.
*
* @param args The command line arguments.
* @return The process exit code.
*/
- protected int run(String[] args) {
+ protected int run(final String[] args) {
try {
LOG.debug("All environment variables: {}", ENV);
- final UserGroupInformation currentUser;
+ // loading all config values here has the advantage that the program fails fast, if any
+ // configuration problem occurs
+
+ CommandLineParser parser = new PosixParser();
+ CommandLine cmd = parser.parse(ALL_OPTIONS, args);
+
+ final Configuration dynamicProperties = BootstrapTools.parseDynamicProperties(cmd);
+ GlobalConfiguration.setDynamicProperties(dynamicProperties);
+ final Configuration config = GlobalConfiguration.loadConfiguration();
+
+ // configure the default filesystem
try {
- currentUser = UserGroupInformation.getCurrentUser();
- } catch (Throwable t) {
- throw new Exception("Cannot access UserGroupInformation information for current user", t);
+ FileSystem.setDefaultScheme(config);
+ } catch (IOException e) {
+ throw new IOException("Error while setting the default " +
+ "filesystem scheme from configuration.", e);
}
- LOG.info("Running Flink as user {}", currentUser.getShortUserName());
+ // configure security
+ SecurityContext.SecurityConfiguration sc = new SecurityContext.SecurityConfiguration(config);
+ sc.setHadoopConfiguration(HadoopUtils.getHadoopConfiguration());
+ SecurityContext.install(sc);
- // run the actual work in a secured privileged action
- return currentUser.doAs(new PrivilegedAction() {
+ // run the actual work in the installed security context
+ return SecurityContext.getInstalled().runSecured(new SecurityContext.FlinkSecuredRunner() {
@Override
- public Integer run() {
- return runPrivileged();
+ public Integer run() throws Exception {
+ return runPrivileged(config, dynamicProperties);
}
});
}
@@ -162,7 +193,7 @@ public Integer run() {
*
* @return The return code for the Java process.
*/
- protected int runPrivileged() {
+ protected int runPrivileged(Configuration config, Configuration dynamicProperties) {
ActorSystem actorSystem = null;
WebMonitor webMonitor = null;
@@ -171,59 +202,15 @@ protected int runPrivileged() {
try {
// ------- (1) load and parse / validate all configurations -------
- // loading all config values here has the advantage that the program fails fast, if any
- // configuration problem occurs
-
- final String workingDir = ENV.get(MesosConfigKeys.ENV_MESOS_SANDBOX);
- checkState(workingDir != null, "Sandbox directory variable (%s) not set", MesosConfigKeys.ENV_MESOS_SANDBOX);
-
- final String sessionID = ENV.get(MesosConfigKeys.ENV_SESSION_ID);
- checkState(sessionID != null, "Session ID (%s) not set", MesosConfigKeys.ENV_SESSION_ID);
-
// Note that we use the "appMasterHostname" given by the system, to make sure
// we use the hostnames consistently throughout akka.
// for akka "localhost" and "localhost.localdomain" are different actors.
final String appMasterHostname = InetAddress.getLocalHost().getHostName();
- // Flink configuration
- final Configuration dynamicProperties =
- FlinkMesosSessionCli.decodeDynamicProperties(ENV.get(MesosConfigKeys.ENV_DYNAMIC_PROPERTIES));
- LOG.debug("Mesos dynamic properties: {}", dynamicProperties);
-
- final Configuration config = createConfiguration(workingDir, dynamicProperties);
-
// Mesos configuration
final MesosConfiguration mesosConfig = createMesosConfig(config, appMasterHostname);
- // environment values related to TM
- final int taskManagerContainerMemory;
- final int numInitialTaskManagers;
- final int slotsPerTaskManager;
-
- try {
- taskManagerContainerMemory = Integer.parseInt(ENV.get(MesosConfigKeys.ENV_TM_MEMORY));
- } catch (NumberFormatException e) {
- throw new RuntimeException("Invalid value for " + MesosConfigKeys.ENV_TM_MEMORY + " : "
- + e.getMessage());
- }
- try {
- numInitialTaskManagers = Integer.parseInt(ENV.get(MesosConfigKeys.ENV_TM_COUNT));
- } catch (NumberFormatException e) {
- throw new RuntimeException("Invalid value for " + MesosConfigKeys.ENV_TM_COUNT + " : "
- + e.getMessage());
- }
- try {
- slotsPerTaskManager = Integer.parseInt(ENV.get(MesosConfigKeys.ENV_SLOTS));
- } catch (NumberFormatException e) {
- throw new RuntimeException("Invalid value for " + MesosConfigKeys.ENV_SLOTS + " : "
- + e.getMessage());
- }
-
- final ContaineredTaskManagerParameters containeredParameters =
- ContaineredTaskManagerParameters.create(config, taskManagerContainerMemory, slotsPerTaskManager);
-
- final MesosTaskManagerParameters taskManagerParameters =
- MesosTaskManagerParameters.create(config, containeredParameters);
+ final MesosTaskManagerParameters taskManagerParameters = MesosTaskManagerParameters.create(config);
LOG.info("TaskManagers will be created with {} task slots",
taskManagerParameters.containeredParameters().numSlots());
@@ -234,7 +221,7 @@ protected int runPrivileged() {
taskManagerParameters.containeredParameters().taskManagerDirectMemoryLimitMB(),
taskManagerParameters.cpus());
- // JM endpoint, which should be explicitly configured by the dispatcher (based on acquired net resources)
+ // JM endpoint, which should be explicitly configured based on acquired net resources
final int listeningPort = config.getInteger(ConfigConstants.JOB_MANAGER_IPC_PORT_KEY,
ConfigConstants.DEFAULT_JOB_MANAGER_IPC_PORT);
checkState(listeningPort >= 0 && listeningPort <= 65536, "Config parameter \"" +
@@ -256,18 +243,28 @@ protected int runPrivileged() {
LOG.debug("Starting Artifact Server");
final int artifactServerPort = config.getInteger(ConfigConstants.MESOS_ARTIFACT_SERVER_PORT_KEY,
ConfigConstants.DEFAULT_MESOS_ARTIFACT_SERVER_PORT);
- artifactServer = new MesosArtifactServer(sessionID, akkaHostname, artifactServerPort);
+ final String artifactServerPrefix = UUID.randomUUID().toString();
+ artifactServer = new MesosArtifactServer(artifactServerPrefix, akkaHostname, artifactServerPort);
// ----------------- (3) Generate the configuration for the TaskManagers -------------------
+ // generate a container spec which conveys the artifacts/vars needed to launch a TM
+ ContainerSpecification taskManagerContainerSpec = new ContainerSpecification();
+
+ // propagate the AM dynamic configuration to the TM
+ taskManagerContainerSpec.getDynamicConfiguration().addAll(dynamicProperties);
+
+ // propagate newly-generated configuration elements
final Configuration taskManagerConfig = BootstrapTools.generateTaskManagerConfiguration(
- config, akkaHostname, akkaPort, slotsPerTaskManager, TASKMANAGER_REGISTRATION_TIMEOUT);
- LOG.debug("TaskManager configuration: {}", taskManagerConfig);
+ new Configuration(), akkaHostname, akkaPort, taskManagerParameters.containeredParameters().numSlots(),
+ TASKMANAGER_REGISTRATION_TIMEOUT);
+ taskManagerContainerSpec.getDynamicConfiguration().addAll(taskManagerConfig);
- final Protos.TaskInfo.Builder taskManagerContext = createTaskManagerContext(
- config, ENV,
- taskManagerParameters, taskManagerConfig,
- workingDir, getTaskManagerClass(), artifactServer, LOG);
+ // apply the overlays
+ applyOverlays(config, taskManagerContainerSpec);
+
+ // configure the artifact server to serve the specified artifacts
+ configureArtifactServer(artifactServer, taskManagerContainerSpec);
// ----------------- (4) start the actors -------------------
@@ -315,8 +312,8 @@ protected int runPrivileged() {
workerStore,
leaderRetriever,
taskManagerParameters,
- taskManagerContext,
- numInitialTaskManagers,
+ taskManagerContainerSpec,
+ artifactServer,
LOG);
ActorRef resourceMaster = actorSystem.actorOf(resourceMasterProps, "Mesos_Resource_Master");
@@ -407,37 +404,12 @@ protected Class extends MemoryArchivist> getArchivistClass() {
return MemoryArchivist.class;
}
- protected Class extends TaskManager> getTaskManagerClass() {
- return MesosTaskManager.class;
- }
-
- /**
- *
- * @param baseDirectory
- * @param additional
- *
- * @return The configuration to be used by the TaskManagers.
- */
- private static Configuration createConfiguration(String baseDirectory, Configuration additional) {
- LOG.info("Loading config from directory {}", baseDirectory);
-
- Configuration configuration = GlobalConfiguration.loadConfiguration(baseDirectory);
-
- configuration.setString(ConfigConstants.FLINK_BASE_DIR_PATH_KEY, baseDirectory);
-
- // add dynamic properties to JobManager configuration.
- configuration.addAll(additional);
-
- return configuration;
- }
-
/**
* Loads and validates the ResourceManager Mesos configuration from the given Flink configuration.
*/
public static MesosConfiguration createMesosConfig(Configuration flinkConfig, String hostname) {
Protos.FrameworkInfo.Builder frameworkInfo = Protos.FrameworkInfo.newBuilder()
- .setUser("")
.setHostname(hostname);
Protos.Credential.Builder credential = null;
@@ -461,6 +433,10 @@ public static MesosConfiguration createMesosConfig(Configuration flinkConfig, St
ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_ROLE,
ConfigConstants.DEFAULT_MESOS_RESOURCEMANAGER_FRAMEWORK_ROLE));
+ frameworkInfo.setUser(flinkConfig.getString(
+ ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_USER,
+ ConfigConstants.DEFAULT_MESOS_RESOURCEMANAGER_FRAMEWORK_USER));
+
if(flinkConfig.containsKey(ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_PRINCIPAL)) {
frameworkInfo.setPrincipal(flinkConfig.getString(
ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_PRINCIPAL, null));
@@ -468,15 +444,16 @@ public static MesosConfiguration createMesosConfig(Configuration flinkConfig, St
credential = Protos.Credential.newBuilder();
credential.setPrincipal(frameworkInfo.getPrincipal());
- if(!flinkConfig.containsKey(ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET)) {
- throw new IllegalConfigurationException(ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET + " must be configured.");
+ // some environments use a side-channel to communicate the secret to Mesos,
+ // and thus don't set the 'secret' configuration setting
+ if(flinkConfig.containsKey(ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET)) {
+ credential.setSecret(flinkConfig.getString(
+ ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET, null));
}
- credential.setSecret(flinkConfig.getString(
- ConfigConstants.MESOS_RESOURCEMANAGER_FRAMEWORK_SECRET, null));
}
MesosConfiguration mesos =
- new MesosConfiguration(masterUrl, frameworkInfo, Option.apply(credential));
+ new MesosConfiguration(masterUrl, frameworkInfo, scala.Option.apply(credential));
return mesos;
}
@@ -500,107 +477,34 @@ else if (recoveryMode == HighAvailabilityMode.ZOOKEEPER) {
}
/**
- * Creates a Mesos task info template, which describes how to bring up a TaskManager process as
- * a Mesos task.
+ * Generate a container specification as a TaskManager template.
*
*
This code is extremely Mesos-specific and registers all the artifacts that the TaskManager
- * needs (such as JAR file, config file, ...) and all environment variables in a task info record.
+ * needs (such as JAR file, config file, ...) and all environment variables into a container specification.
* The Mesos fetcher then ensures that those artifacts will be copied into the task's sandbox directory.
* A lightweight HTTP server serves the artifacts to the fetcher.
- *
- *
We do this work before we start the ResourceManager actor in order to fail early if
- * any of the operations here fail.
- *
- * @param flinkConfig
- * The Flink configuration object.
- * @param env
- * The environment variables.
- * @param tmParams
- * The TaskManager container memory parameters.
- * @param taskManagerConfig
- * The configuration for the TaskManagers.
- * @param workingDirectory
- * The current application master container's working directory.
- * @param taskManagerMainClass
- * The class with the main method.
- * @param artifactServer
- * The artifact server.
- * @param log
- * The logger.
- *
- * @return The task info template for the TaskManager processes.
- *
- * @throws Exception Thrown if the task info could not be created, for example if
- * the resources could not be copied.
- */
- public static Protos.TaskInfo.Builder createTaskManagerContext(
- Configuration flinkConfig,
- Map env,
- MesosTaskManagerParameters tmParams,
- Configuration taskManagerConfig,
- String workingDirectory,
- Class> taskManagerMainClass,
- MesosArtifactServer artifactServer,
- Logger log) throws Exception {
-
-
- Protos.TaskInfo.Builder info = Protos.TaskInfo.newBuilder();
- Protos.CommandInfo.Builder cmd = Protos.CommandInfo.newBuilder();
-
- log.info("Setting up artifacts for TaskManagers");
-
- String shipListString = env.get(MesosConfigKeys.ENV_CLIENT_SHIP_FILES);
- checkState(shipListString != null, "Environment variable %s not set", MesosConfigKeys.ENV_CLIENT_SHIP_FILES);
-
- String clientUsername = env.get(MesosConfigKeys.ENV_CLIENT_USERNAME);
- checkState(clientUsername != null, "Environment variable %s not set", MesosConfigKeys.ENV_CLIENT_USERNAME);
-
- String classPathString = env.get(MesosConfigKeys.ENV_FLINK_CLASSPATH);
- checkState(classPathString != null, "Environment variable %s not set", MesosConfigKeys.ENV_FLINK_CLASSPATH);
-
- // register the Flink jar
- final File flinkJarFile = new File(workingDirectory, "flink.jar");
- cmd.addUris(uri(artifactServer.addFile(flinkJarFile, "flink.jar"), true));
-
- // register the TaskManager configuration
- final File taskManagerConfigFile =
- new File(workingDirectory, UUID.randomUUID() + "-taskmanager-conf.yaml");
- LOG.debug("Writing TaskManager configuration to {}", taskManagerConfigFile.getAbsolutePath());
- BootstrapTools.writeConfiguration(taskManagerConfig, taskManagerConfigFile);
- cmd.addUris(uri(artifactServer.addFile(taskManagerConfigFile, GlobalConfiguration.FLINK_CONF_FILENAME), true));
-
- // prepare additional files to be shipped
- for (String pathStr : shipListString.split(",")) {
- if (!pathStr.isEmpty()) {
- File shipFile = new File(workingDirectory, pathStr);
- cmd.addUris(uri(artifactServer.addFile(shipFile, shipFile.getName()), true));
- }
- }
-
- log.info("Creating task info for TaskManagers");
-
- // build the launch command
- boolean hasLogback = new File(workingDirectory, "logback.xml").exists();
- boolean hasLog4j = new File(workingDirectory, "log4j.properties").exists();
- boolean hasKrb5 = false;
-
- String launchCommand = BootstrapTools.getTaskManagerShellCommand(
- flinkConfig, tmParams.containeredParameters(), ".", ".",
- hasLogback, hasLog4j, hasKrb5, taskManagerMainClass);
- cmd.setValue(launchCommand);
+ */
+ private static void applyOverlays(
+ Configuration globalConfiguration, ContainerSpecification containerSpec) throws IOException {
+
+ // create the overlays that will produce the specification
+ CompositeContainerOverlay overlay = new CompositeContainerOverlay(
+ FlinkDistributionOverlay.newBuilder().fromEnvironment(globalConfiguration).build(),
+ HadoopConfOverlay.newBuilder().fromEnvironment(globalConfiguration).build(),
+ HadoopUserOverlay.newBuilder().fromEnvironment(globalConfiguration).build(),
+ KeytabOverlay.newBuilder().fromEnvironment(globalConfiguration).build(),
+ Krb5ConfOverlay.newBuilder().fromEnvironment(globalConfiguration).build(),
+ SSLStoreOverlay.newBuilder().fromEnvironment(globalConfiguration).build()
+ );
+
+ // apply the overlays
+ overlay.configure(containerSpec);
+ }
- // build the environment variables
- Protos.Environment.Builder envBuilder = Protos.Environment.newBuilder();
- for (Map.Entry entry : tmParams.containeredParameters().taskManagerEnv().entrySet()) {
- envBuilder.addVariables(variable(entry.getKey(), entry.getValue()));
+ private static void configureArtifactServer(MesosArtifactServer server, ContainerSpecification container) throws IOException {
+ // serve the artifacts associated with the container environment
+ for(ContainerSpecification.Artifact artifact : container.getArtifacts()) {
+ server.addPath(artifact.source, artifact.dest);
}
- envBuilder.addVariables(variable(MesosConfigKeys.ENV_CLASSPATH, classPathString));
- envBuilder.addVariables(variable(MesosConfigKeys.ENV_CLIENT_USERNAME, clientUsername));
-
- cmd.setEnvironment(envBuilder);
-
- info.setCommand(cmd);
-
- return info;
}
}
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosConfigKeys.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosConfigKeys.java
index 9413c685ffedb..ebd9af5709fbf 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosConfigKeys.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosConfigKeys.java
@@ -26,18 +26,20 @@ public class MesosConfigKeys {
// Environment variable names
// ------------------------------------------------------------------------
- public static final String ENV_TM_MEMORY = "_CLIENT_TM_MEMORY";
- public static final String ENV_TM_COUNT = "_CLIENT_TM_COUNT";
- public static final String ENV_SLOTS = "_SLOTS";
- public static final String ENV_CLIENT_SHIP_FILES = "_CLIENT_SHIP_FILES";
- public static final String ENV_CLIENT_USERNAME = "_CLIENT_USERNAME";
- public static final String ENV_DYNAMIC_PROPERTIES = "_DYNAMIC_PROPERTIES";
+ /**
+ * The Mesos task ID, used by the TM for informational purposes
+ */
public static final String ENV_FLINK_CONTAINER_ID = "_FLINK_CONTAINER_ID";
+
+ /**
+ * Reserved for future enhancement
+ */
public static final String ENV_FLINK_TMP_DIR = "_FLINK_TMP_DIR";
- public static final String ENV_FLINK_CLASSPATH = "_FLINK_CLASSPATH";
- public static final String ENV_CLASSPATH = "CLASSPATH";
- public static final String ENV_MESOS_SANDBOX = "MESOS_SANDBOX";
- public static final String ENV_SESSION_ID = "_CLIENT_SESSION_ID";
+
+ /**
+ * JVM arguments, used by the JM and TM
+ */
+ public static final String ENV_JVM_ARGS = "JVM_ARGS";
/** Private constructor to prevent instantiation */
private MesosConfigKeys() {}
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosFlinkResourceManager.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosFlinkResourceManager.java
index 6b24ee8944697..2f677f59211db 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosFlinkResourceManager.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosFlinkResourceManager.java
@@ -27,6 +27,7 @@
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.ConfigConstants;
import org.apache.flink.configuration.Configuration;
+import org.apache.flink.configuration.IllegalConfigurationException;
import org.apache.flink.mesos.runtime.clusterframework.store.MesosWorkerStore;
import org.apache.flink.mesos.scheduler.ConnectionMonitor;
import org.apache.flink.mesos.scheduler.LaunchableTask;
@@ -44,9 +45,11 @@
import org.apache.flink.mesos.scheduler.messages.Registered;
import org.apache.flink.mesos.scheduler.messages.ResourceOffers;
import org.apache.flink.mesos.scheduler.messages.StatusUpdate;
+import org.apache.flink.mesos.util.MesosArtifactResolver;
import org.apache.flink.mesos.util.MesosConfiguration;
import org.apache.flink.runtime.clusterframework.ApplicationStatus;
import org.apache.flink.runtime.clusterframework.FlinkResourceManager;
+import org.apache.flink.runtime.clusterframework.ContainerSpecification;
import org.apache.flink.runtime.clusterframework.messages.FatalErrorOccurred;
import org.apache.flink.runtime.clusterframework.messages.StopCluster;
import org.apache.flink.runtime.clusterframework.types.ResourceID;
@@ -76,8 +79,11 @@ public class MesosFlinkResourceManager extends FlinkResourceManager();
@@ -661,7 +669,7 @@ private void taskTerminated(Protos.TaskID taskID, Protos.TaskStatus status) {
private LaunchableMesosWorker createLaunchableMesosWorker(Protos.TaskID taskID) {
LaunchableMesosWorker launchable =
- new LaunchableMesosWorker(taskManagerParameters, taskManagerLaunchContext, taskID);
+ new LaunchableMesosWorker(artifactResolver, taskManagerParameters, taskManagerContainerSpec, taskID);
return launchable;
}
@@ -723,10 +731,10 @@ public TaskScheduler build() {
* The Flink configuration object.
* @param taskManagerParameters
* The parameters for launching TaskManager containers.
- * @param taskManagerLaunchContext
- * The parameters for launching the TaskManager processes in the TaskManager containers.
- * @param numInitialTaskManagers
- * The initial number of TaskManagers to allocate.
+ * @param taskManagerContainerSpec
+ * The container specification.
+ * @param artifactResolver
+ * The artifact resolver to locate artifacts
* @param log
* The logger to log to.
*
@@ -738,10 +746,22 @@ public static Props createActorProps(Class extends MesosFlinkResourceManager>
MesosWorkerStore workerStore,
LeaderRetrievalService leaderRetrievalService,
MesosTaskManagerParameters taskManagerParameters,
- Protos.TaskInfo.Builder taskManagerLaunchContext,
- int numInitialTaskManagers,
+ ContainerSpecification taskManagerContainerSpec,
+ MesosArtifactResolver artifactResolver,
Logger log)
{
+
+ final int numInitialTaskManagers = flinkConfig.getInteger(
+ ConfigConstants.MESOS_INITIAL_TASKS, 1);
+ if (numInitialTaskManagers >= 1) {
+ log.info("Mesos framework to allocate {} initial tasks",
+ numInitialTaskManagers);
+ }
+ else {
+ throw new IllegalConfigurationException("Invalid value for " +
+ ConfigConstants.MESOS_INITIAL_TASKS + ", which must be at least one.");
+ }
+
final int maxFailedTasks = flinkConfig.getInteger(
ConfigConstants.MESOS_MAX_FAILED_TASKS, numInitialTaskManagers);
if (maxFailedTasks >= 0) {
@@ -755,7 +775,8 @@ public static Props createActorProps(Class extends MesosFlinkResourceManager>
workerStore,
leaderRetrievalService,
taskManagerParameters,
- taskManagerLaunchContext,
+ taskManagerContainerSpec,
+ artifactResolver,
maxFailedTasks,
numInitialTaskManagers);
}
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerParameters.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerParameters.java
index 1b19d0837bad1..86c4ece240a4c 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerParameters.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerParameters.java
@@ -19,10 +19,12 @@
package org.apache.flink.mesos.runtime.clusterframework;
import org.apache.flink.configuration.ConfigConstants;
+import org.apache.flink.configuration.ConfigOption;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.runtime.clusterframework.ContaineredTaskManagerParameters;
import static java.util.Objects.requireNonNull;
+import static org.apache.flink.configuration.ConfigOptions.key;
/**
* This class describes the Mesos-specific parameters for launching a TaskManager process.
@@ -32,9 +34,21 @@
*/
public class MesosTaskManagerParameters {
- private double cpus;
+ public static final ConfigOption MESOS_RM_TASKS_SLOTS =
+ key(ConfigConstants.TASK_MANAGER_NUM_TASK_SLOTS)
+ .defaultValue(1);
- private ContaineredTaskManagerParameters containeredParameters;
+ public static final ConfigOption MESOS_RM_TASKS_MEMORY_MB =
+ key("mesos.resourcemanager.tasks.mem")
+ .defaultValue(1024);
+
+ public static final ConfigOption MESOS_RM_TASKS_CPUS =
+ key("mesos.resourcemanager.tasks.cpus")
+ .defaultValue(0.0);
+
+ private final double cpus;
+
+ private final ContaineredTaskManagerParameters containeredParameters;
public MesosTaskManagerParameters(double cpus, ContaineredTaskManagerParameters containeredParameters) {
requireNonNull(containeredParameters);
@@ -67,14 +81,19 @@ public String toString() {
/**
* Create the Mesos TaskManager parameters.
* @param flinkConfig the TM configuration.
- * @param containeredParameters additional containered parameters.
*/
- public static MesosTaskManagerParameters create(
- Configuration flinkConfig,
- ContaineredTaskManagerParameters containeredParameters) {
+ public static MesosTaskManagerParameters create(Configuration flinkConfig) {
+
+ // parse the common parameters
+ ContaineredTaskManagerParameters containeredParameters = ContaineredTaskManagerParameters.create(
+ flinkConfig,
+ flinkConfig.getInteger(MESOS_RM_TASKS_MEMORY_MB),
+ flinkConfig.getInteger(MESOS_RM_TASKS_SLOTS));
- double cpus = flinkConfig.getDouble(ConfigConstants.MESOS_RESOURCEMANAGER_TASKS_CPUS,
- Math.max(containeredParameters.numSlots(), 1.0));
+ double cpus = flinkConfig.getDouble(MESOS_RM_TASKS_CPUS);
+ if(cpus <= 0.0) {
+ cpus = Math.max(containeredParameters.numSlots(), 1.0);
+ }
return new MesosTaskManagerParameters(cpus, containeredParameters);
}
diff --git a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerRunner.java b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerRunner.java
index ddc2097221e1e..0d19d8b6e314a 100644
--- a/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerRunner.java
+++ b/flink-mesos/src/main/java/org/apache/flink/mesos/runtime/clusterframework/MesosTaskManagerRunner.java
@@ -19,22 +19,26 @@
package org.apache.flink.mesos.runtime.clusterframework;
import java.io.IOException;
-import java.security.PrivilegedAction;
import java.util.Map;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
+import org.apache.flink.api.java.hadoop.mapred.utils.HadoopUtils;
import org.apache.flink.configuration.ConfigConstants;
import org.apache.flink.configuration.Configuration;
-import org.apache.flink.mesos.cli.FlinkMesosSessionCli;
+import org.apache.flink.configuration.GlobalConfiguration;
+import org.apache.flink.core.fs.FileSystem;
+import org.apache.flink.runtime.clusterframework.BootstrapTools;
import org.apache.flink.runtime.clusterframework.types.ResourceID;
+import org.apache.flink.runtime.security.SecurityContext;
import org.apache.flink.runtime.taskmanager.TaskManager;
import org.apache.flink.runtime.util.EnvironmentInformation;
import org.apache.flink.runtime.util.JvmShutdownSafeguard;
import org.apache.flink.runtime.util.SignalHandler;
import org.apache.flink.util.Preconditions;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.security.token.Token;
-import org.apache.hadoop.security.token.TokenIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,24 +50,33 @@ public class MesosTaskManagerRunner {
private static final Logger LOG = LoggerFactory.getLogger(MesosTaskManagerRunner.class);
+ private static final Options ALL_OPTIONS;
+
+ static {
+ ALL_OPTIONS =
+ new Options()
+ .addOption(BootstrapTools.newDynamicPropertiesOption());
+ }
+
/** The process environment variables */
private static final Map ENV = System.getenv();
- public static void runTaskManager(String[] args, final Class extends TaskManager> taskManager) throws IOException {
+ public static void runTaskManager(String[] args, final Class extends TaskManager> taskManager) throws Exception {
EnvironmentInformation.logEnvironmentInfo(LOG, taskManager.getSimpleName(), args);
SignalHandler.register(LOG);
JvmShutdownSafeguard.installAsShutdownHook(LOG);
// try to parse the command line arguments
+ CommandLineParser parser = new PosixParser();
+ CommandLine cmd = parser.parse(ALL_OPTIONS, args);
+
final Configuration configuration;
try {
- configuration = TaskManager.parseArgsAndLoadConfig(args);
-
- // add dynamic properties to TaskManager configuration.
- final Configuration dynamicProperties =
- FlinkMesosSessionCli.decodeDynamicProperties(ENV.get(MesosConfigKeys.ENV_DYNAMIC_PROPERTIES));
+ final Configuration dynamicProperties = BootstrapTools.parseDynamicProperties(cmd);
+ GlobalConfiguration.setDynamicProperties(dynamicProperties);
LOG.debug("Mesos dynamic properties: {}", dynamicProperties);
- configuration.addAll(dynamicProperties);
+
+ configuration = GlobalConfiguration.loadConfiguration();
}
catch (Throwable t) {
LOG.error("Failed to load the TaskManager configuration and dynamic properties.", t);
@@ -73,7 +86,6 @@ public static void runTaskManager(String[] args, final Class extends TaskManag
// read the environment variables
final Map envs = System.getenv();
- final String effectiveUsername = envs.get(MesosConfigKeys.ENV_CLIENT_USERNAME);
final String tmpDirs = envs.get(MesosConfigKeys.ENV_FLINK_TMP_DIR);
// configure local directory
@@ -87,34 +99,39 @@ else if (tmpDirs != null) {
configuration.setString(ConfigConstants.TASK_MANAGER_TMP_DIR_KEY, tmpDirs);
}
- LOG.info("Mesos task runs as '{}', setting user to execute Flink TaskManager to '{}'",
- UserGroupInformation.getCurrentUser().getShortUserName(), effectiveUsername);
+ // configure the default filesystem
+ try {
+ FileSystem.setDefaultScheme(configuration);
+ } catch (IOException e) {
+ throw new IOException("Error while setting the default " +
+ "filesystem scheme from configuration.", e);
+ }
// tell akka to die in case of an error
configuration.setBoolean(ConfigConstants.AKKA_JVM_EXIT_ON_FATAL_ERROR, true);
- UserGroupInformation ugi = UserGroupInformation.createRemoteUser(effectiveUsername);
- for (Token extends TokenIdentifier> toks : UserGroupInformation.getCurrentUser().getTokens()) {
- ugi.addToken(toks);
- }
-
// Infer the resource identifier from the environment variable
String containerID = Preconditions.checkNotNull(envs.get(MesosConfigKeys.ENV_FLINK_CONTAINER_ID));
final ResourceID resourceId = new ResourceID(containerID);
LOG.info("ResourceID assigned for this container: {}", resourceId);
- ugi.doAs(new PrivilegedAction