Merge "Check for remote server exec failures and report"
This commit is contained in:
commit
79bb1594b4
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2009, Google Inc.
|
* Copyright (C) 2008-2010, Google Inc.
|
||||||
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
|
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
|
||||||
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
|
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
|
||||||
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
|
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
|
||||||
|
@ -127,6 +127,23 @@ private static void sq(final StringBuilder cmd, final String val) {
|
||||||
cmd.append(QuotedString.BOURNE.quote(val));
|
cmd.append(QuotedString.BOURNE.quote(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String commandFor(final String exe) {
|
||||||
|
String path = uri.getPath();
|
||||||
|
if (uri.getScheme() != null && uri.getPath().startsWith("/~"))
|
||||||
|
path = (uri.getPath().substring(1));
|
||||||
|
|
||||||
|
final StringBuilder cmd = new StringBuilder();
|
||||||
|
final int gitspace = exe.indexOf("git ");
|
||||||
|
if (gitspace >= 0) {
|
||||||
|
sqMinimal(cmd, exe.substring(0, gitspace + 3));
|
||||||
|
cmd.append(' ');
|
||||||
|
sqMinimal(cmd, exe.substring(gitspace + 4));
|
||||||
|
} else
|
||||||
|
sqMinimal(cmd, exe);
|
||||||
|
cmd.append(' ');
|
||||||
|
sqAlways(cmd, path);
|
||||||
|
return cmd.toString();
|
||||||
|
}
|
||||||
|
|
||||||
ChannelExec exec(final String exe) throws TransportException {
|
ChannelExec exec(final String exe) throws TransportException {
|
||||||
initSession();
|
initSession();
|
||||||
|
@ -134,21 +151,7 @@ ChannelExec exec(final String exe) throws TransportException {
|
||||||
final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
|
final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
|
||||||
try {
|
try {
|
||||||
final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
|
final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
|
||||||
String path = uri.getPath();
|
channel.setCommand(commandFor(exe));
|
||||||
if (uri.getScheme() != null && uri.getPath().startsWith("/~"))
|
|
||||||
path = (uri.getPath().substring(1));
|
|
||||||
|
|
||||||
final StringBuilder cmd = new StringBuilder();
|
|
||||||
final int gitspace = exe.indexOf("git ");
|
|
||||||
if (gitspace >= 0) {
|
|
||||||
sqMinimal(cmd, exe.substring(0, gitspace + 3));
|
|
||||||
cmd.append(' ');
|
|
||||||
sqMinimal(cmd, exe.substring(gitspace + 4));
|
|
||||||
} else
|
|
||||||
sqMinimal(cmd, exe);
|
|
||||||
cmd.append(' ');
|
|
||||||
sqAlways(cmd, path);
|
|
||||||
channel.setCommand(cmd.toString());
|
|
||||||
errStream = createErrorStream();
|
errStream = createErrorStream();
|
||||||
channel.setErrStream(errStream, true);
|
channel.setErrStream(errStream, true);
|
||||||
channel.connect(tms);
|
channel.connect(tms);
|
||||||
|
@ -158,6 +161,17 @@ ChannelExec exec(final String exe) throws TransportException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkExecFailure(int status, String exe) throws TransportException {
|
||||||
|
if (status == 127) {
|
||||||
|
String why = errStream.toString();
|
||||||
|
IOException cause = null;
|
||||||
|
if (why != null && why.length() > 0)
|
||||||
|
cause = new IOException(why);
|
||||||
|
throw new TransportException(uri, "cannot execute: "
|
||||||
|
+ commandFor(exe), cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the error stream for the channel, the stream is used to detect
|
* @return the error stream for the channel, the stream is used to detect
|
||||||
* specific error reasons for exceptions.
|
* specific error reasons for exceptions.
|
||||||
|
@ -305,6 +319,8 @@ public void run() {
|
||||||
class SshFetchConnection extends BasePackFetchConnection {
|
class SshFetchConnection extends BasePackFetchConnection {
|
||||||
private ChannelExec channel;
|
private ChannelExec channel;
|
||||||
|
|
||||||
|
private int exitStatus;
|
||||||
|
|
||||||
SshFetchConnection() throws TransportException {
|
SshFetchConnection() throws TransportException {
|
||||||
super(TransportGitSsh.this);
|
super(TransportGitSsh.this);
|
||||||
try {
|
try {
|
||||||
|
@ -327,6 +343,8 @@ class SshFetchConnection extends BasePackFetchConnection {
|
||||||
try {
|
try {
|
||||||
readAdvertisedRefs();
|
readAdvertisedRefs();
|
||||||
} catch (NoRemoteRepositoryException notFound) {
|
} catch (NoRemoteRepositoryException notFound) {
|
||||||
|
close();
|
||||||
|
checkExecFailure(exitStatus, getOptionUploadPack());
|
||||||
throw cleanNotFound(notFound);
|
throw cleanNotFound(notFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,6 +355,7 @@ public void close() {
|
||||||
|
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
try {
|
try {
|
||||||
|
exitStatus = channel.getExitStatus();
|
||||||
if (channel.isConnected())
|
if (channel.isConnected())
|
||||||
channel.disconnect();
|
channel.disconnect();
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -349,6 +368,8 @@ public void close() {
|
||||||
class SshPushConnection extends BasePackPushConnection {
|
class SshPushConnection extends BasePackPushConnection {
|
||||||
private ChannelExec channel;
|
private ChannelExec channel;
|
||||||
|
|
||||||
|
private int exitStatus;
|
||||||
|
|
||||||
SshPushConnection() throws TransportException {
|
SshPushConnection() throws TransportException {
|
||||||
super(TransportGitSsh.this);
|
super(TransportGitSsh.this);
|
||||||
try {
|
try {
|
||||||
|
@ -371,6 +392,8 @@ class SshPushConnection extends BasePackPushConnection {
|
||||||
try {
|
try {
|
||||||
readAdvertisedRefs();
|
readAdvertisedRefs();
|
||||||
} catch (NoRemoteRepositoryException notFound) {
|
} catch (NoRemoteRepositoryException notFound) {
|
||||||
|
close();
|
||||||
|
checkExecFailure(exitStatus, getOptionReceivePack());
|
||||||
throw cleanNotFound(notFound);
|
throw cleanNotFound(notFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,6 +404,7 @@ public void close() {
|
||||||
|
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
try {
|
try {
|
||||||
|
exitStatus = channel.getExitStatus();
|
||||||
if (channel.isConnected())
|
if (channel.isConnected())
|
||||||
channel.disconnect();
|
channel.disconnect();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in New Issue