Subject: [bug#30809] [PATCH 2/2] services: Add Gitolite.

From: Clément Lassieur <[email-masked]>
Date: Tue, 31 Jul 2018 01:39:00 +0200

Hey Christopher!

Thank you for the update.

Christopher Baines <[email-masked]> writes:

[...]

> +@example
> +git clone git@@example.com:gitolite-admin
> +@end example
> +
> +When the Gitolite service is activated, the provided @code{admin-pubkey} will
> +be inserted in to the @file{keydir} directory in the gitolite-admin
> +repository.  If this results in a change in the repository, it will be
> +committed using the message ``gitolite setup by GNU Guix''.
> +
> +@deftp {Data Type} gitolite-configuration
> +Data type representing the configuration for @code{gitolite-service-type}.
> +
> +@table @asis
> +@item @code{package} (default: @var{gitolite})
> +Gitolite package to use.
> +
> +@item @code{user} (default: @var{git})
                                    ^
It should be a string ---------------

I don't think you should use @var for default values.  @code would be better.

> +User to use for Gitolite.  This will be user that you use when accessing
> +Gitolite over SSH.
> +
> +@item @code{group} (default: @var{git})
                                    ^
It should be a string ---------------

> +Group to use for Gitolite.
> +
> +@item @code{home-directory} (default: @var{"/var/lib/gitolite"})
> +Directory in which to store the Gitolite configuration and repositories.
> +
> +@item @code{rc-file} (default: @var{(gitolite-rc-file)})
> +A ``file-like'' object (@pxref{G-Expressions, file-like objects}),
> +representing the configuration for Gitolite.
> +
> +@item @code{admin-pubkey} (default: @var{#f})

Actually, there is no default :-)

[...]

> +  (match-lambda
> +    (($ <gitolite-configuration> package user group home
> +                                 rc-file admin-pubkey)
> +     #~(let* ((user-info (getpwnam #$user))
> +              (admin-pubkey #$admin-pubkey)
> +              (pubkey-file (string-append
> +                            #$home "/"
> +                            (basename
> +                             (strip-store-file-name admin-pubkey)))))
> +         (use-modules (guix build utils))
> +
> +         (simple-format #t "guix: gitolite: installing ~A\n" #$rc-file)
> +         (copy-file #$rc-file #$(string-append home "/.gitolite.rc"))
                 ^
Maybe a symlink here?

> +         ;; The key must be writable, so copy it from the store
> +         (copy-file admin-pubkey pubkey-file)
> +
> +         (chmod pubkey-file #o500)

I don't think it must be writable, because #o500 isn't writable.

> +         (chown pubkey-file
> +                (passwd:uid user-info)
> +                (passwd:gid user-info))
> +
> +         ;; Set the git configuration, to avoid gitolite trying to use
> +         ;; the hostname command, as the network might not be up yet
> +         (with-output-to-file #$(string-append home "/.gitconfig")
> +           (lambda ()
> +             (display "[user]
> +        name = GNU Guix
> +        email = guix@localhost
> +")))
> +         ;; Run Gitolite setup, as this updates the hooks and include the
> +         ;; admin pubkey if specified. The admin pubkey is required for
> +         ;; initial setup, and will replace the previous key if run after
> +         ;; initial setup
> +         (let ((pid (primitive-fork)))
> +           (if (eq? pid 0)
> +               ;; Exit with a non-zero status code if an exception is thrown.
> +               (dynamic-wind
> +                 (const #t)
> +                 (lambda ()
> +                   (setenv "HOME" (passwd:dir user-info))
> +                   (setenv "USER" #$user)
> +                   (setgid (passwd:gid user-info))
> +                   (setuid (passwd:uid user-info))
> +                   (primitive-exit
> +                    (system* #$(file-append package "/bin/gitolite")
> +                             "setup"
> +                             "-m" "gitolite setup by GNU Guix"
> +                             "-pk" pubkey-file)))
> +                 (lambda ()
> +                   (primitive-exit 1)))
> +               (waitpid pid)))

This works (with the (ice-9 match) module added):

         (match (primitive-fork)
           (0
            ;; Exit with a non-zero status code if an exception is thrown.
            (dynamic-wind
              (const #t)
              (lambda ()
                (setenv "HOME" (passwd:dir user-info))
                (setenv "USER" #$user)
                (setgid (passwd:gid user-info))
                (setuid (passwd:uid user-info))
                (primitive-exit
                 (system* #$(file-append package "/bin/gitolite")
                          "setup"
                          "-m" "gitolite setup by GNU Guix"
                          "-pk" pubkey-file)))
              (lambda ()
                (primitive-exit 1))))
           (pid (waitpid pid)))

Other than that, it looks good to me!

Thanks again,
Clément