[snowpatch] [PATCH] Replace ssh agent authentication with explicit key

Andrew Donnellan andrew.donnellan at au1.ibm.com
Thu Dec 1 17:04:49 AEDT 2016


From: Russell Currey <ruscur at russell.cc>

libgit2 has a long-standing obscure bug where it gets in an infinite loop
calling ssh-agent.  ssh-agent has been a pain point in snowpatch for a
while now, so let's just not use it - instead, manually specify public and
private keys.  This adds the benefit of configuring the user ("git" was
hardcoded for GitHub/GitLab previously) as well as passphrase support.

Future possibility: support parsing "~/" in the settings file.

Signed-off-by: Russell Currey <ruscur at russell.cc>
---
 examples/openpower.toml |  5 +++++
 src/git.rs              | 15 ++++++++++++++-
 src/main.rs             |  4 ++--
 src/settings.rs         |  9 +++++++++
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/examples/openpower.toml b/examples/openpower.toml
index 5c0ba40..d582576 100644
--- a/examples/openpower.toml
+++ b/examples/openpower.toml
@@ -14,6 +14,11 @@
 # openpower.toml - example configuration file
 #
 
+[git]
+user = "git"
+public_key = "/home/ruscur/.ssh/id_rsa.pub"
+private_key = "/home/ruscur/.ssh/id_rsa"
+
 [patchwork]
 url = "https://russell.cc/patchwork"
 port = 443 #optional
diff --git a/src/git.rs b/src/git.rs
index 679d387..ac4c95e 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -14,13 +14,15 @@
 // git.rs - snowpatch git functionality
 //
 
-use git2::{Repository, Commit, Remote, Error, PushOptions};
+use git2::{Repository, Commit, Remote, Error, PushOptions, Cred};
 use git2::build::CheckoutBuilder;
 
 use std::result::Result;
 use std::path::Path;
 use std::process::{Command, Output};
 
+use settings::Git;
+
 pub static GIT_REF_BASE: &'static str = "refs/heads";
 
 pub fn get_latest_commit(repo: &Repository) -> Commit {
@@ -85,6 +87,17 @@ pub fn apply_patch(repo: &Repository, path: &Path)
     }
 }
 
+pub fn cred_from_settings(settings: &Git) -> Result<Cred, Error> {
+    // We have to convert from Option<String> to Option<&str>
+    let public_key = settings.public_key.as_ref().map(String::as_ref);
+    let passphrase = settings.passphrase.as_ref().map(String::as_ref);
+
+    Cred::ssh_key(&settings.user,
+                  public_key,
+                  Path::new(&settings.private_key),
+                  passphrase)
+}
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/src/main.rs b/src/main.rs
index 426bfdf..07fd32e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -30,7 +30,7 @@ extern crate url;
 extern crate log;
 extern crate env_logger;
 
-use git2::{Cred, BranchType, RemoteCallbacks, PushOptions};
+use git2::{BranchType, RemoteCallbacks, PushOptions};
 
 use hyper::Client;
 
@@ -150,7 +150,7 @@ fn test_patch(settings: &Config, client: &Arc<Client>, project: &Project, path:
 
     let mut push_callbacks = RemoteCallbacks::new();
     push_callbacks.credentials(|_, _, _| {
-        return Cred::ssh_key_from_agent("git");
+        git::cred_from_settings(&settings.git)
     });
 
     let mut push_opts = PushOptions::new();
diff --git a/src/settings.rs b/src/settings.rs
index a4a5614..b440885 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -28,6 +28,14 @@ use std::collections::BTreeMap;
 // TODO: Give more informative error messages when we fail to parse.
 
 #[derive(RustcDecodable, Clone)]
+pub struct Git {
+    pub user: String,
+    pub public_key: Option<String>,
+    pub private_key: String,
+    pub passphrase: Option<String>
+}
+
+#[derive(RustcDecodable, Clone)]
 pub struct Patchwork {
     pub url: String,
     pub port: Option<u16>,
@@ -65,6 +73,7 @@ impl Project {
 
 #[derive(RustcDecodable, Clone)]
 pub struct Config {
+    pub git: Git,
     pub patchwork: Patchwork,
     pub jenkins: Jenkins,
     pub projects: BTreeMap<String, Project>
-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan at au1.ibm.com  IBM Australia Limited



More information about the snowpatch mailing list