diff mbox

Replace ssh agent authentication with explicit key

Message ID 20170203043837.14426-1-andrew.donnellan@au1.ibm.com
State Accepted
Headers show

Commit Message

Andrew Donnellan Feb. 3, 2017, 4:38 a.m. UTC
From: Russell Currey <ruscur@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@russell.cc>
Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

---

already merged, for information only

---
 examples/openpower.toml |  5 +++++
 src/git.rs              | 15 ++++++++++++++-
 src/main.rs             |  4 ++--
 src/settings.rs         |  9 +++++++++
 4 files changed, 30 insertions(+), 3 deletions(-)
diff mbox

Patch

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 51362b5..e67caac 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 {
@@ -89,6 +91,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 af488f3..0913277 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -31,7 +31,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;
 use hyper::client::ProxyConfig;
@@ -155,7 +155,7 @@  fn test_patch(settings: &Config, client: &Arc<Client>, project: &Project, path:
 
     let mut push_callbacks = RemoteCallbacks::new();
     push_callbacks.credentials(|_, _, _| {
-        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 4e91244..2d30e7c 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>