summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjemstep-edward <42668885+jemstep-edward@users.noreply.github.com>2020-03-04 10:47:17 +0200
committerGitHub <noreply@github.com>2020-03-04 10:47:17 +0200
commit9f792b1b2154dc4f0a2e54cabf7c75d7e700ce81 (patch)
tree67dae2673528cca86a831a555efff5ec65ce2583
parentd5c752e36d88d048be20e6e525d0146b0d2f0a81 (diff)
parent126f5dc06e6ebe8f5eb267cc67f6916c610ab554 (diff)
Merge pull request #48 from jemstep/github-prereceive-environment
GitHub prereceive sandbox environment
-rw-r--r--.gitignore3
-rw-r--r--github/Dockerfile3
-rwxr-xr-xgithub/create-github-pre-receive-environment.sh18
-rw-r--r--github/readme.org31
-rw-r--r--readme.org34
-rw-r--r--src/gpg.rs9
6 files changed, 93 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index f2e972d..9a5b046 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
# These are backup files generated by rustfmt
**/*.rs.bk
+
+# Pre-receive sandbox environment generated from script
+capn-pre-receive.tar.gz
diff --git a/github/Dockerfile b/github/Dockerfile
new file mode 100644
index 0000000..f8a1e8d
--- /dev/null
+++ b/github/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:18.04
+RUN apt-get update && apt-get install -y git gnupg1 && ln -s /usr/bin/gpg1 /usr/bin/gpg
+
diff --git a/github/create-github-pre-receive-environment.sh b/github/create-github-pre-receive-environment.sh
new file mode 100755
index 0000000..976262b
--- /dev/null
+++ b/github/create-github-pre-receive-environment.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+SCRIPT_DIR=$(dirname "$0")
+
+if ! command -v docker >/dev/null 2>&1; then
+ echo "Docker does not appear to be installed."
+ echo "Please install Docker and ensure that it is on the path."
+ exit 1
+fi
+
+docker rm capn-pre-receive || true
+docker build -f $SCRIPT_DIR/Dockerfile -t capn-pre-receive $SCRIPT_DIR
+docker create --name capn-pre-receive capn-pre-receive /bin/true
+docker export capn-pre-receive | gzip > capn-pre-receive.tar.gz
+
+echo "Successfully created capn-pre-receive.tar.gz"
diff --git a/github/readme.org b/github/readme.org
new file mode 100644
index 0000000..4f7375c
--- /dev/null
+++ b/github/readme.org
@@ -0,0 +1,31 @@
+* GitHub Enterprise Pre-receive Hook Sandbox Environment
+
+GitHub Enterprise imposes certain additional requirements on running
+server-side pre-receive hooks.
+
+1. The hook has a strict 5 second time limit in which to run.
+2. The hook must run within a sandboxed environment, which only lives
+ for the duration of the hook running. The default does not work for
+ Captain Git Hook because it does not include dirmngr.
+3. GitHub runs the hook in Firejail, which may impose additional
+ limitations. The one that I ran into is that gpg could not
+ communicate with dirmngr over a socket.
+
+A suitable sandbox is specified in [[./Dockerfile]]. You can build this
+Dockerfile into an appropriate tarball for upload to GitHub using the
+script [[./create-github-pre-receive-environment.sh]].
+
+#+BEGIN_SRC sh
+ # we're running the script in the same directory as this readme, but you can run it from anywhere
+ cd github
+
+ # this produces capn-pre-receive.tar.gz
+ ./create-github-pre-receive-environment.sh
+
+ # you can now upload the tarball to GitHub
+#+END_SRC
+
+The following two documents show how to set up this sandbox
+environment on GitHub:
+- [[https://help.github.com/en/enterprise/2.20/admin/developer-workflow/creating-a-pre-receive-hook-environment]]
+- [[https://help.github.com/en/enterprise/2.20/admin/developer-workflow/managing-pre-receive-hooks-on-the-github-enterprise-server-appliance]]
diff --git a/readme.org b/readme.org
index 995d998..035c2dd 100644
--- a/readme.org
+++ b/readme.org
@@ -56,6 +56,15 @@ This will add an executable to your path called ~capn~.
#+END_SRC
** Usage
+*** Runtime Dependencies
+Captain Git Hook requires certain command line applications to be
+installed and on the path.
+- git - This is used as a binary on the CLI only for cases unsupported
+ by libgit2, such as verifying signatures.
+- gpg - This is used for verifying signatures.
+- dirmngr - This is a gpg component that gpg uses as part of fetching
+ gpg keys from a keyserver. On some distros, this is bundled together
+ with gpg.
*** Git Hooks
Captain Git Hook works by installing hooks in your Git repository. Git
@@ -76,6 +85,11 @@ How to install this will depend on how you administrate your Git
server. For example, these are the instructions for GitHub Enterprise:
[[https://help.github.com/en/enterprise/2.19/admin/developer-workflow/managing-pre-receive-hooks-on-the-github-enterprise-server-appliance][Managing pre-receive hooks on the GitHub Enterprise Server appliance]].
+Some Git servers, like GitHub Enterprise, require specifying a sandbox
+environment for the pre-receive hook to run in. For convenience, we
+include a Dockerfile and script for setting up a GitHub Enterprise
+sandbox. [[./github/readme.org]]
+
*** Policy Configuration
The policies that Captain Git Hook will apply for a repo are
@@ -154,6 +168,26 @@ git tag --sign <tag-name>
git push <remote> <tag-name>
#+END_SRC
+*** Monitoring
+By default, logging output is produced to the terminal, following the
+convention of output to stdout, diagnostics to stderr.
+
+Additional diagnostics can be produced to stderr by specifying =-v= or
+=--verbose= on the command line. For example, =capn -v pre-receive=
+will produce debug level logging, which =capn pre-receive= will only
+produce info level logging.
+
+Diagnostic logging over TCP is also supported with the =--log-url=
+command line parameter. Network logs are sent in JSON format.
+
+In the case of network logging, it's usually useful to provide some
+data to contextualise the log. A server side hook using all of the
+context parameters would look like this:
+
+#+BEGIN_SRC rust
+ capn-qa -vv --log-url 10.0.0.123:123 --repo "$GITHUB_REPO_NAME" --user "$GITHUB_USER_LOGIN" --ip "$GITHUB_USER_IP" pre-receive
+#+END_SRC
+
* Development
** High level architecture
diff --git a/src/gpg.rs b/src/gpg.rs
index 78a0648..822f0f9 100644
--- a/src/gpg.rs
+++ b/src/gpg.rs
@@ -92,16 +92,15 @@ impl LiveGpg {
.args(&["--keyserver", &self.keyserver])
.arg("--recv-keys")
.arg(fingerprint)
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .status()?;
+ .output()?;
- if result.success() {
+ if result.status.success() {
Ok(())
} else {
+ debug!("GPG Stderr: {:?}", String::from_utf8(result.stderr));
Err(Box::new(CapnError::new(format!(
"Call to GPG keyserver failed with code {:?}",
- result.code()
+ result.status.code()
))))
}
}