[PATCH consfigurator v2 1/2] GPG: batch mode and return *ERROR-OUTPUT* in conditions
Sean Whitton
spwhitton at spwhitton.name
Mon Oct 3 20:28:15 BST 2022
Hello Russell,
Thanks for this, it will be a nice improvement.
On Wed 21 Sep 2022 at 10:06PM +02, Russell Sim wrote:
> diff --git a/src/data/util.lisp b/src/data/util.lisp
> index aa0451f..b6c8685 100644
> --- a/src/data/util.lisp
> +++ b/src/data/util.lisp
> @@ -19,6 +19,15 @@
> (in-package :consfigurator.data.util)
> (named-readtables:in-readtable :consfigurator)
>
> +(define-condition gpg-error (subprocess-error)
> + ((output :initform nil :initarg :output :reader gpg-error-output))
> + (:report (lambda (condition stream)
> + (format stream "Subprocess ~@[~S~% ~]~@[with command ~S~% ~]exited with error~@[ code ~D~%~]~@[~% with error output:~% ~S~]"
> + (subprocess-error-process condition)
> + (subprocess-error-command condition)
> + (subprocess-error-code condition)
> + (gpg-error-output condition)))))
> +
How about using the RUN-FAILED condition, instead of adding a new one?
> @@ -46,19 +55,28 @@ may contain '/' characters to map into multiple levels of directory."
> INPUT and OUTPUT have the same meaning as for RUN-PROGRAM, except that OUTPUT
> defaults to :STRING. The default return value is thus the output from gnupg,
> as a string."
> - (run-program
> - `("gpg"
> - ,@(and *data-source-gnupghome*
> - (list "--homedir" (namestring *data-source-gnupghome*)))
> - , at args)
> - :input input
> - :output (or output :string)))
> + (let ((error-output (make-string-output-stream)))
> + (handler-case
> + (run-program
> + `("gpg" "-q" "--batch"
> + ,@(and *data-source-gnupghome*
> + (list "--homedir" (namestring *data-source-gnupghome*)))
> + , at args)
> + :input input
> + :error-output error-output
> + :output (or output :string))
> + (subprocess-error (error)
> + (error 'gpg-error
> + :code (subprocess-error-code error)
> + :command (subprocess-error-command error)
> + :process (subprocess-error-process error)
> + :output (get-output-stream-string error-output))))))
Please reformat to avoid overly long lines here.
> (defun gpg-file-as-string (location)
> "Decrypt the contents of a gpg encrypted file at LOCATION, return as a
> string."
> (handler-case
> (gpg (list "--decrypt" (unix-namestring location)))
> - (subprocess-error (error)
> - (missing-data-source "While attempt to decrypt ~A, gpg exited with ~A"
> - location (uiop:subprocess-error-code error)))))
> + (gpg-error (error)
> + (missing-data-source "While attempt to decrypt ~A, gpg exited with ~A~@[~% with gpg error output:~% ~S~]"
> + location (subprocess-error-code error) (gpg-error-output error)))))
Likewise, lines are too long here. Can you use the same format string
as RUN-FAILED, too, for consistency? Like this:
"~&'gpg' failed, exit code ~A~%~%stderr was:~%~A"
> diff --git a/src/package.lisp b/src/package.lisp
> index 4b51b70..55b2d1a 100644
> --- a/src/package.lisp
> +++ b/src/package.lisp
> @@ -1022,7 +1022,11 @@
> (#:lxc #:consfigurator.property.lxc)))
>
> (package :consfigurator.data.util
> - (:export #:literal-data-pathname #:gpg-file-as-string #:gpg))
> + (:import-from #:uiop
> + #:subprocess-error-process
> + #:subprocess-error-command
> + #:subprocess-error-code)
> + (:export #:literal-data-pathname #:gpg-file-as-string #:gpg #:gpg-error))
>
> (package :consfigurator.data.asdf)
Please just import them unconditionally into CONSFIGURATOR, just as is
already done for SUBPROCESS-ERROR itself.
> diff --git a/tests/data/pgp.lisp b/tests/data/pgp.lisp
> index 21ba60c..0eb7749 100644
> --- a/tests/data/pgp.lisp
> +++ b/tests/data/pgp.lisp
> @@ -19,3 +19,12 @@
> (deftest data.pgp.3
> (get-data-string "host.example.com" "/etc/foo.conf")
> "secret file content")
> +
> +(deftest data.pgp.4
> + (handler-case (data.pgp:get-data "/dev/null" "_secrets" "test")
> + (missing-data-source (error)
> + (princ-to-string error)))
> + "While attempt to decrypt /dev/null, gpg exited with 2
> + with gpg error output:
> + \"gpg: decrypt_message failed: Unknown system error
> +\"")
How about just searching for the substring "decrypt_message failed", to
make this a bit less fragile?
--
Sean Whitton
More information about the sgo-software-discuss
mailing list