Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Fix access path propagation on git/ssh protocol

Change-Id: Ia38a54d210fb53dcb36a364f885cb1f2e17abf23
This commit is contained in:
David Pursehouse 2018-10-09 09:25:44 +09:00
commit 914a17d662
2 changed files with 58 additions and 37 deletions

View File

@ -33,8 +33,6 @@ public abstract class AbstractGitCommand extends BaseCommand {
@Argument(index = 0, metaVar = "PROJECT.git", required = true, usage = "project name")
protected ProjectControl projectControl;
@Inject private SshScope sshScope;
@Inject private GitRepositoryManager repoManager;
@Inject private SshSession session;
@ -53,28 +51,25 @@ public abstract class AbstractGitCommand extends BaseCommand {
@Override
public void start(Environment env) {
Context ctx = context.subContext(newSession(), context.getCommandLine());
final Context old = sshScope.set(ctx);
try {
startThread(
new ProjectCommandRunnable() {
@Override
public void executeParseCommand() throws Exception {
parseCommandLine();
}
startThreadWithContext(
ctx,
new ProjectCommandRunnable() {
@Override
public void executeParseCommand() throws Exception {
parseCommandLine();
}
@Override
public void run() throws Exception {
AbstractGitCommand.this.service();
}
@Override
public void run() throws Exception {
AbstractGitCommand.this.service();
}
@Override
public Project.NameKey getProjectName() {
return projectControl.getProjectState().getNameKey();
}
});
} finally {
sshScope.set(old);
}
@Override
public Project.NameKey getProjectName() {
Project project = projectControl.getProjectState().getProject();
return project.getNameKey();
}
});
}
private SshSession newSession() {

View File

@ -49,6 +49,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.Optional;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;
@ -259,6 +260,38 @@ public abstract class BaseCommand implements Command {
return cmdLineParserFactory.create(options);
}
/**
* Spawn a function into its own thread with the provided context.
*
* <p>Typically this should be invoked within {@link Command#start(Environment)}, such as:
*
* <pre>
* startThreadWithContext(SshScope.Context context, new CommandRunnable() {
* public void run() throws Exception {
* runImp();
* }
* });
* </pre>
*
* <p>If the function throws an exception, it is translated to a simple message for the client, a
* non-zero exit code, and the stack trace is logged.
*
* @param thunk the runnable to execute on the thread, performing the command's logic.
*/
protected void startThreadWithContext(SshScope.Context context, CommandRunnable thunk) {
final TaskThunk tt = new TaskThunk(thunk, Optional.ofNullable(context));
if (isAdminHighPriorityCommand()) {
// Admin commands should not block the main work threads (there
// might be an interactive shell there), nor should they wait
// for the main work threads.
//
new Thread(tt, tt.toString()).start();
} else {
task.set(executor.submit(tt));
}
}
/**
* Spawn a function into its own thread.
*
@ -277,18 +310,8 @@ public abstract class BaseCommand implements Command {
*
* @param thunk the runnable to execute on the thread, performing the command's logic.
*/
protected void startThread(CommandRunnable thunk) {
final TaskThunk tt = new TaskThunk(thunk);
if (isAdminHighPriorityCommand()) {
// Admin commands should not block the main work threads (there
// might be an interactive shell there), nor should they wait
// for the main work threads.
//
new Thread(tt, tt.toString()).start();
} else {
task.set(executor.submit(tt));
}
protected void startThread(final CommandRunnable thunk) {
startThreadWithContext(null, thunk);
}
private boolean isAdminHighPriorityCommand() {
@ -413,18 +436,21 @@ public abstract class BaseCommand implements Command {
private final class TaskThunk implements CancelableRunnable, ProjectRunnable {
private final CommandRunnable thunk;
private final Context taskContext;
private final String taskName;
private Project.NameKey projectName;
private TaskThunk(CommandRunnable thunk) {
private TaskThunk(CommandRunnable thunk, Optional<Context> oneOffContext) {
this.thunk = thunk;
this.taskName = getTaskName();
this.taskContext = oneOffContext.orElse(context);
}
@Override
public void cancel() {
synchronized (this) {
final Context old = sshScope.set(context);
final Context old = sshScope.set(taskContext);
try {
onExit(STATUS_CANCEL);
} finally {
@ -439,7 +465,7 @@ public abstract class BaseCommand implements Command {
final Thread thisThread = Thread.currentThread();
final String thisName = thisThread.getName();
int rc = 0;
final Context old = sshScope.set(context);
final Context old = sshScope.set(taskContext);
try {
context.started = TimeUtil.nowMs();
thisThread.setName("SSH " + taskName);