mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
user should have option to run these interpreters as different user.
This commit is contained in:
parent
575467055f
commit
aff1bf0645
10 changed files with 83 additions and 21 deletions
|
|
@ -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=$!
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;">
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;">
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue