Browse Source

Check for remote server exec failures and report

If remote.name.uploadpack or .receivepack is misconfigured and points
to a non-existent command on the remote system, we should receive back
exit status 127.  Report this case specially with the command we used
so the user knows what is going.

Bug: 293703
Change-Id: I7504e7b6238d5d8e698d37db7411c4817a039d08
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
stable-0.7
Shawn O. Pearce 15 years ago
parent
commit
08a77c04b4
  1. 56
      org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java

56
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java

@ -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 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
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 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
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 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
} }
} }
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 class TransportGitSsh extends SshTransport implements PackTransport {
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 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
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 class TransportGitSsh extends SshTransport implements PackTransport {
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 class TransportGitSsh extends SshTransport implements PackTransport {
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 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
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 class TransportGitSsh extends SshTransport implements PackTransport {
if (channel != null) { if (channel != null) {
try { try {
exitStatus = channel.getExitStatus();
if (channel.isConnected()) if (channel.isConnected())
channel.disconnect(); channel.disconnect();
} finally { } finally {

Loading…
Cancel
Save