user should have option to run these interpreters as different user.

This commit is contained in:
Prabhjyot Singh 2016-10-23 13:16:59 +05:30
parent 575467055f
commit aff1bf0645
10 changed files with 83 additions and 21 deletions

View file

@ -23,7 +23,7 @@ function usage() {
echo "usage) $0 -p <port> -d <interpreter dir to load> -l <local interpreter repo dir to load>"
}
while getopts "hp:d:l:v" o; do
while getopts "hp:d:l:v:u:" o; do
case ${o} in
h)
usage
@ -42,6 +42,9 @@ while getopts "hp:d:l:v" o; do
. "${bin}/common.sh"
getZeppelinVersion
;;
u)
ZEPPELIN_SSH_COMMAND="ssh ${OPTARG}@localhost "
;;
esac
done
@ -178,9 +181,9 @@ addJarInDirForIntp "${LOCAL_INTERPRETER_REPO}"
CLASSPATH+=":${ZEPPELIN_INTP_CLASSPATH}"
if [[ -n "${SPARK_SUBMIT}" ]]; then
${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path "${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH}" --driver-java-options "${JAVA_INTP_OPTS}" ${SPARK_SUBMIT_OPTIONS} ${SPARK_APP_JAR} ${PORT} &
${ZEPPELIN_SSH_COMMAND} `${SPARK_SUBMIT} --class ${ZEPPELIN_SERVER} --driver-class-path "${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH}" --driver-java-options "${JAVA_INTP_OPTS}" ${SPARK_SUBMIT_OPTIONS} ${SPARK_APP_JAR} ${PORT} &`
else
${ZEPPELIN_RUNNER} ${JAVA_INTP_OPTS} ${ZEPPELIN_INTP_MEM} -cp ${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH} ${ZEPPELIN_SERVER} ${PORT} &
${ZEPPELIN_SSH_COMMAND} ${ZEPPELIN_RUNNER} ${JAVA_INTP_OPTS} ${ZEPPELIN_INTP_MEM} -cp ${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${CLASSPATH} ${ZEPPELIN_SERVER} ${PORT} &
fi
pid=$!

View file

@ -59,6 +59,8 @@ public class RemoteInterpreter extends Interpreter {
private int maxPoolSize;
private String host;
private int port;
private String userName;
private Boolean isUserImpersonate;
/**
* Remote interpreter and manage interpreter process
@ -72,7 +74,9 @@ public class RemoteInterpreter extends Interpreter {
int connectTimeout,
int maxPoolSize,
RemoteInterpreterProcessListener remoteInterpreterProcessListener,
ApplicationEventListener appListener) {
ApplicationEventListener appListener,
String userName,
Boolean isUserImpersonate) {
super(property);
this.noteId = noteId;
this.className = className;
@ -85,6 +89,8 @@ public class RemoteInterpreter extends Interpreter {
this.maxPoolSize = maxPoolSize;
this.remoteInterpreterProcessListener = remoteInterpreterProcessListener;
this.applicationEventListener = appListener;
this.userName = userName;
this.isUserImpersonate = isUserImpersonate;
}
@ -100,7 +106,9 @@ public class RemoteInterpreter extends Interpreter {
int connectTimeout,
int maxPoolSize,
RemoteInterpreterProcessListener remoteInterpreterProcessListener,
ApplicationEventListener appListener) {
ApplicationEventListener appListener,
String userName,
Boolean isUserImpersonate) {
super(property);
this.noteId = noteId;
this.className = className;
@ -111,6 +119,8 @@ public class RemoteInterpreter extends Interpreter {
this.maxPoolSize = maxPoolSize;
this.remoteInterpreterProcessListener = remoteInterpreterProcessListener;
this.applicationEventListener = appListener;
this.userName = userName;
this.isUserImpersonate = isUserImpersonate;
}
@ -125,7 +135,9 @@ public class RemoteInterpreter extends Interpreter {
Map<String, String> env,
int connectTimeout,
RemoteInterpreterProcessListener remoteInterpreterProcessListener,
ApplicationEventListener appListener) {
ApplicationEventListener appListener,
String userName,
Boolean isUserImpersonate) {
super(property);
this.className = className;
this.noteId = noteId;
@ -138,6 +150,8 @@ public class RemoteInterpreter extends Interpreter {
this.maxPoolSize = 10;
this.remoteInterpreterProcessListener = remoteInterpreterProcessListener;
this.applicationEventListener = appListener;
this.userName = userName;
this.isUserImpersonate = isUserImpersonate;
}
private Map<String, String> getEnvFromInterpreterProperty(Properties property) {
@ -205,7 +219,7 @@ public class RemoteInterpreter extends Interpreter {
RemoteInterpreterProcess interpreterProcess = getInterpreterProcess();
final InterpreterGroup interpreterGroup = getInterpreterGroup();
interpreterProcess.reference(interpreterGroup);
interpreterProcess.reference(interpreterGroup, userName, isUserImpersonate);
interpreterProcess.setMaxPoolSize(
Math.max(this.maxPoolSize, interpreterProcess.getMaxPoolSize()));
String groupId = interpreterGroup.getId();

View file

@ -88,7 +88,7 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
}
@Override
public void start() {
public void start(String userName, Boolean isUserImpersonate) {
// start server process
try {
port = RemoteInterpreterUtils.findRandomAvailablePortOnAllLocalInterfaces();
@ -101,6 +101,10 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
cmdLine.addArgument(interpreterDir, false);
cmdLine.addArgument("-p", false);
cmdLine.addArgument(Integer.toString(port), false);
if (isUserImpersonate && !userName.equals("anonymous")) {
cmdLine.addArgument("-u", false);
cmdLine.addArgument(userName, false);
}
cmdLine.addArgument("-l", false);
cmdLine.addArgument(localRepoDir, false);

View file

@ -63,7 +63,7 @@ public abstract class RemoteInterpreterProcess {
public abstract String getHost();
public abstract int getPort();
public abstract void start();
public abstract void start(String userName, Boolean isUserImpersonate);
public abstract void stop();
public abstract boolean isRunning();
@ -71,10 +71,11 @@ public abstract class RemoteInterpreterProcess {
return connectTimeout;
}
public int reference(InterpreterGroup interpreterGroup) {
public int reference(InterpreterGroup interpreterGroup, String userName,
Boolean isUserImpersonate) {
synchronized (referenceCount) {
if (!isRunning()) {
start();
start(userName, isUserImpersonate);
}
if (clientPool == null) {

View file

@ -51,7 +51,7 @@ public class RemoteInterpreterRunningProcess extends RemoteInterpreterProcess {
}
@Override
public void start() {
public void start(String userName, Boolean isUserImpersonate) {
// assume process is externally managed. nothing to do
}

View file

@ -196,7 +196,19 @@ limitations under the License.
</div>
</div>
</div>
<div class="row interpreter" style="margin-top: 5px;">
<div class="row interpreter" style="margin-top: 5px;" ng-hide="ticket.principal=='anonymous'">
<div class="col-md-12">
<div class="checkbox remove-margin-top-bottom">
<span class="input-group" style="line-height:30px;">
<label>
<input type="checkbox" style="width:20px" ng-model="setting.option.isUserImpersonate" />
User Impersonate
</label>
</span>
</div>
</div>
</div>
<div class="row interpreter">
<div class="col-md-12">
<div class="checkbox remove-margin-top-bottom">
<span class="input-group" style="line-height:30px;">

View file

@ -326,6 +326,9 @@
if (setting.option.setPermission === undefined) {
setting.option.setPermission = false;
}
if (setting.option.isUserImpersonate === undefined) {
setting.option.isUserImpersonate = false;
}
if (setting.option.remote === undefined) {
// remote always true for now
setting.option.remote = true;

View file

@ -309,7 +309,22 @@ limitations under the License.
</div>
</div>
</div>
<div class="row interpreter" style="margin-top: 5px;">
<div class="row interpreter" style="margin-top: 5px;" ng-hide="ticket.principal=='anonymous'">
<div class="col-md-12">
<div class="checkbox remove-margin-top-bottom">
<span class="input-group" style="line-height:30px;">
<label>
<input type="checkbox" style="width:20px"
ng-model="setting.option.isUserImpersonate"
ng-disabled="!valueform.$visible" />
User Impersonate
</label>
</span>
</div>
</div>
</div>
<div class="row interpreter">
<div class="col-md-12">
<div class="checkbox remove-margin-top-bottom">
<span class="input-group" style="line-height:30px;">

View file

@ -762,10 +762,10 @@ public class InterpreterFactory implements InterpreterGroupFactory {
if (option.isExistingProcess()) {
interpreter =
connectToRemoteRepl(noteId, info.getClassName(), option.getHost(), option.getPort(),
properties);
properties, user, option.isUserImpersonate);
} else {
interpreter = createRemoteRepl(path, key, info.getClassName(), properties,
interpreterSetting.getId());
interpreterSetting.getId(), user, option.isUserImpersonate());
}
} else {
interpreter = createRepl(interpreterSetting.getPath(), info.getClassName(), properties);
@ -1069,17 +1069,18 @@ public class InterpreterFactory implements InterpreterGroupFactory {
}
private Interpreter connectToRemoteRepl(String noteId, String className, String host, int port,
Properties property) {
Properties property, String userName, Boolean isUserImpersonate) {
int connectTimeout = conf.getInt(ConfVars.ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT);
int maxPoolSize = conf.getInt(ConfVars.ZEPPELIN_INTERPRETER_MAX_POOL_SIZE);
LazyOpenInterpreter intp = new LazyOpenInterpreter(
new RemoteInterpreter(property, noteId, className, host, port, connectTimeout, maxPoolSize,
remoteInterpreterProcessListener, appEventListener));
remoteInterpreterProcessListener, appEventListener, userName, isUserImpersonate));
return intp;
}
private Interpreter createRemoteRepl(String interpreterPath, String noteId, String className,
Properties property, String interpreterSettingId) {
Properties property, String interpreterSettingId, String userName,
Boolean isUserImpersonate) {
int connectTimeout = conf.getInt(ConfVars.ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT);
String localRepoPath = conf.getInterpreterLocalRepoPath() + "/" + interpreterSettingId;
int maxPoolSize = conf.getInt(ConfVars.ZEPPELIN_INTERPRETER_MAX_POOL_SIZE);
@ -1087,7 +1088,7 @@ public class InterpreterFactory implements InterpreterGroupFactory {
RemoteInterpreter remoteInterpreter =
new RemoteInterpreter(property, noteId, className, conf.getInterpreterRemoteRunnerPath(),
interpreterPath, localRepoPath, connectTimeout, maxPoolSize,
remoteInterpreterProcessListener, appEventListener);
remoteInterpreterProcessListener, appEventListener, userName, isUserImpersonate);
remoteInterpreter.addEnv(env);
return new LazyOpenInterpreter(remoteInterpreter);
@ -1385,7 +1386,7 @@ public class InterpreterFactory implements InterpreterGroupFactory {
InterpreterGroup interpreterGroup = createInterpreterGroup("dev", option);
devInterpreter = connectToRemoteRepl("dev", DevInterpreter.class.getName(), "localhost",
ZeppelinDevServer.DEFAULT_TEST_INTERPRETER_PORT, new Properties());
ZeppelinDevServer.DEFAULT_TEST_INTERPRETER_PORT, new Properties(), "anonymous", false);
LinkedList<Interpreter> intpList = new LinkedList<>();
intpList.add(devInterpreter);

View file

@ -39,6 +39,7 @@ public class InterpreterOption {
boolean isExistingProcess;
boolean setPermission;
List<String> users;
boolean isUserImpersonate;
public boolean isExistingProcess() {
return isExistingProcess;
@ -68,6 +69,14 @@ public class InterpreterOption {
return users;
}
public boolean isUserImpersonate() {
return isUserImpersonate;
}
public void setUserImpersonate(boolean userImpersonate) {
isUserImpersonate = userImpersonate;
}
public InterpreterOption() {
this(false);
}