从MVC的WebAPI调用时的Git / SSH挂 [英] Git/SSH hanging when called from MVC WebApi

查看:104
本文介绍了从MVC的WebAPI调用时的Git / SSH挂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个项目,我的工作(在Windows,C#,MVC4的WebAPI)的一部分,需要与git的一些集成。现有的C#的Git库中没有支持的远程克隆,所以我结束了移植 JavaGit 我们需要项目的部分(结帐,取,状态),写克隆自己。所有这真的是是一个包装到git的命令行可执行文件。有关code调用是在这里:

Part of a project I'm working on (Windows, C#, MVC4 WebAPI) requires some integration with git. None of the existing C# git libraries supported remote cloning, so I wound up porting the parts of the JavaGit project we needed (checkout, fetch, status), and writing clone myself. All it really is is a wrapper to the git command line executable. The relevant code it calls is here:

public static void RunGitCommand(string repositoryPath, string gitArguments)
{
    // GitCommand is the full path to git.exe (currently using Github for Windows)
    if (null == GitCommand || String.IsNullOrWhiteSpace(GitCommand))
    {
        throw new FileNotFoundException("Unable to find git.exe on your system PATH.");
    }

    // gitArguments contains the command to run (e.g. "clone -- git@repo:projectName c:\repositories\repo_a8c0dd321f")
    var startInfo = new ProcessStartInfo(GitCommand, gitArguments)
    {
        WorkingDirectory = (null != repositoryPath && Directory.Exists(repositoryPath)) ? repositoryPath : String.Empty,
        CreateNoWindow = true,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardInput = true,
        RedirectStandardError = true
    };

    using (var p = new Process
    {
        EnableRaisingEvents = true,
        StartInfo = startInfo
    })
    {
        p.OutputDataReceived += (sender, args) => Log.Debug(args.Data);

        p.ErrorDataReceived += (sender, args) => Log.Debug(args.Data);

        p.Start();

        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        p.WaitForExit();
    }
}

这将在code作为被称为:

Which would be called by the code as:

// names changed to protect the innocent
string localRepo = @"c:\repositories\repo_a8c0dd321f";
string gitArgs = "clone -- git@repo:projectName c:\repositories\repo_a8c0dd321f";

GitConfiguration.RunGitCommand(localRepo, gitArgs);

从MVC API中,我们使用模拟,以确保它的运行与有效的git的用户名和密钥(没有密码)的用户。上面的命令在命令行作为自己完美的作品,并以快速的单元测试,以及(我知道这是一个真正的集成测试)。

From within the MVC API, we use impersonation to make sure it's running as a user with a valid git login and key (no passphrase). The command above works perfectly from a command line as myself, and in an quick unit test, as well (I know it's really an integration test).

然而,当如上所示的实际上是从该API调用时,它挂起。展望任务管理器显示git.exe运行,表现为git.exe接着上面的参数的完整路径的命令行。它不使用任何处理器时间的,只有RAM 2604K,但它声称在运行。同样,有一个ssh.exe进程在运行,也没有处理器使用率和内存1212K,使用命令行:

However, when it's actually called from the API as shown above, it hangs. Looking in Task Manager shows git.exe running, with the command line showing the full path to git.exe followed by the arguments above. It's not using any processor time, and only 2604K of RAM, but it claims to be running. Likewise, there is an ssh.exe process running, also with no processor usage, and 1212K of RAM, with the command line:

ssh git@repo "git-upload-pack 'projectName'"

这两个进程被列为我的用户名下运行,所以会出现模拟运行正常。

Both processes are listed as running under my username, so it appears impersonation is working correctly.

展望在localRepo目录,它创建的.git目录,然后挂起,周围留下13K值得的Git的文件在那里,但没有我们的code的。我以为这是由于我们的回购是巨大的,我让它运行过夜。仍然没有动静截至今天上午。

Looking in the localRepo directory, it creates the .git directory, then hangs, leaving around 13K worth of git files in there, but none of our code. Thinking it was due to our repo being huge, I let it run overnight. Still no movement as of this morning.

长大LINQPad,跑到:

Brought up LINQPad, ran:

Process.GetProcessById($gitPID).Dump()

有没有为SSH过程一样好。该线显示了他们在等待状态之中,而WaitReason是执行(等待线程调度器)。我最初以为它正在等待一个密码,因为我的钥匙有一个。我切换到一个工作重点没有密码,相同的结果。

Did the same for the SSH process as well. The threads showed them as being in the Wait state, and the WaitReason was Executive (waiting for thread scheduler). I initially assumed it was waiting for a passphrase, as my key had one. I switched to a working key without a passphrase, same result.

Git/SSH versions (from latest GitHub for Windows):
    git version
        git version 1.7.11.msysgit.1
    ssh -v
        OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007


我已经离开了唯一的想法是,也许它不能与ssh-agent的,这是运行通信。这是冒充我正确的,虽然如此,我不知道为什么它不会从框架的WebAPI的工作,但是从单位测试和Git壳牌工作正常。我试图确保了HOME,PLINK_PROTOCOL,期限,SSH_AUTH_SOCK和SSH_AGENT_PID环境变量分别设置,通过Github上的Windows安装脚本照看,只是为了确保我没有错过什么。


The only idea I have left is that maybe it can't communicate with ssh-agent, which is running. It is impersonating me properly, though, so I don't know why it wouldn't work from the WebApi framework, but works fine from the "unit" test and Git Shell. I tried making sure the HOME, PLINK_PROTOCOL, TERM, SSH_AUTH_SOCK, and SSH_AGENT_PID environment variables were set, after looking through the Github for Windows setup scripts, just to make sure I wasn't missing anything.

我在全盘损失。下面是日志文件的片段,与一些意见之后:

I'm at a total loss. Here's a snippet of the log file, with some comments afterward:

2012-11-20 13:42:59.5898 Info Initializing repo at path: c:\repositories\repo_a8c0dd321f 
2012-11-20 13:42:59.5898 Debug Working Directory: c:\repositories\repo_a8c0dd321f 
2012-11-20 13:42:59.6053 Debug C:\Users\christian.doggett\AppData\Local\GitHub\PortableGit_8810fd5c2c79c73adcc73fd0825f3b32fdb816e7\bin\git.exe status --branch 
2012-11-20 13:42:59.6209 Debug HOME=H:\ 
2012-11-20 13:42:59.6209 Debug PLINK_PROTOCOL=ssh 
2012-11-20 13:42:59.6365 Debug TERM=msys 
2012-11-20 13:42:59.6365 Debug SSH_AGENT_PID=58416 
2012-11-20 13:42:59.6365 Debug SSH_AUTH_SOCK=/tmp/ssh-IgTHj19056/agent.19056 
2012-11-20 13:42:59.6521 Info git status --branch
Exit code: 128

2012-11-20 13:42:59.6521 Error  
2012-11-20 13:42:59.6677 Info Cloning repo from origin: git@repo:projectName 
2012-11-20 13:43:01.8674 Debug Cloning into 'c:\repositories\repo_a8c0dd321f'... 
2012-11-20 13:43:03.2090 Debug Could not create directory 'h/.ssh'. 
2012-11-20 13:43:03.2870 Debug Warning: Permanently added 'repo,359.33.9.234' (RSA) to the list of known hosts. 
2012-11-20 13:44:41.4593 Debug fatal: The remote end hung up unexpectedly 

我总是得到无法创建目录'H /的.ssh'和警告:永久添加*到已知主机列表邮件,即使是在命令行上。我的H:的.ssh \\ known_hosts里面是空的,但我的钥匙就在该目录中,和git查找这些就好了。在远端挂了意外当我杀了Git和SSH流程错误了。

I always get the "Could not create directory 'h/.ssh'" and "Warning: Permanently added * to the list of known hosts." messages, even on the command line. My H:.ssh\known_hosts remains empty, but my keys are in that directory, and git finds those just fine. The "remote end hung up unexpectedly" error was when I killed the git and ssh processes.

我可能结业切换到LibGit2Sharp的大部分我的需要,但是仍然没有解决我的问题的克隆。是什么搞砸了我的钥匙设置,这再次,完美的作品W3wp.exe进程之外吗?是否需要能够使用ssh-agent.exe沟通,是不是能?有没有人通过的System.Diagnostics.Process克隆远程git仓库,住讲的故事?

I may wind up switching to LibGit2Sharp for most of my needs, but that still doesn't solve my clone problem. Is something screwed up with my key setup, which again, works perfectly outside of the w3wp.exe process? Does it need to be able to communicate with ssh-agent.exe, and is not able to? Has anyone cloned a remote git repository via System.Diagnostics.Process and lived to tell the tale?

更新(2012年11月25日下午6点54分):

MVP是指出正确的模拟和映射的网络驱动器不玩好起来。我添加了以下启动过程之前:

mvp was correct in pointing out that impersonation and mapped network drives don't play well together. I added the following before starting the process:

var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
Environment.SetEnvironmentVariable("HOME", userProfile);

我又跑了,和我现在至少看到在服用的处理器0的时间,但使用的内存越来越多的任务管理器一个新的git的过程,我相信作为克隆过程的一部分。命令行是:

I ran it again, and am now at least seeing a new git process in Task Manager that's taking 0 processor time, but is using an increasing amount of memory, I believe as part of the clone process. The command line was:

git index-pack --stdin --fix-thin "--keep=fetch-pack 6024 on MACHINENAME"

这只是10分钟(这是一个巨大的资源库)后,终于完成了,并引发异常:

It just finally finished after 10 minutes (It's a huge repository), and threw the exception:

fatal: git checkout: updating paths is incompatible with switching branches.
Did you intend to checkout 'origin/8b243b8d9a5140673fc552ef7da8f0dfe9039d50' which can not be resolved as commit?

看起来像克隆改变进入目录后的工作,但!另一个问题是事做克隆操作完成后立即打电话结账,但无关的悬挂问题。

Looks like the clone worked after changing into the directory, though! The other problem is something to do with immediately calling checkout after the clone operation finishes, but is unrelated to the hanging problem.

我只需要确认在生产服务器上我/ MVP的解决方案,然后我会奖赏金。

I just need to verify my/mvp's solution on a production server, then I'll award the bounty.

推荐答案

我相信你的主要问题是,对模拟的帐户的主目录是不是你认为它是,主要是因为网络映射驱动器的模拟帐户的真的不工作

I believe your main problem is that home directory for impersonated account is not what you think it is, mostly because network mapped drives for impersonated accounts don't really work.

作为一种解决方法,你应该设置HOME环境变量的模拟用户指向一些本地目录(假设驱动器 C:),它应该包含您的SSH密钥(不口令)。你应该通过运行 git的克隆手动(虽然具有有效的假HOME)测试一下,并接受known_host键,所以它不会prevent背景git的命令自动工作。

As a workaround, you should set HOME environment variable for impersonated user to point to some local directory (say on drive C:) which should contain your ssh keys (without passphrases). You should test this by running git clone manually (while having fake HOME in effect) and accept known_host keys, so it would not prevent background git command from working automatically.

这篇关于从MVC的WebAPI调用时的Git / SSH挂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆