Subject: ansible: Work around issues with Guix wrapper scripts
From: Arun Isaac <[email-masked]>
To: [email-masked]
Date: Mon, 17 Dec 2018 19:40:51 +0530
List-Id: <debbugs-submit.debbugs.gnu.org>

This patch works around ansible's issues with Guix wrapper scripts. The
earlier system using ansible-wrap-program-hack.patch was not working as
expected.

From 2a8d3b46aac378b077fb9ef296909c840fa9c42a Mon Sep 17 00:00:00 2001
From: Arun Isaac <[email-masked]>
Date: Mon, 17 Dec 2018 19:32:05 +0530
Subject: [PATCH] gnu: ansible: Work around issues with Guix wrapper scripts.

* gnu/packages/admin.scm (ansible)[source]: Remove
ansible-wrap-program-hack.patch from patches.
[arguments]: Add hide-wrapping and fix-symlinks phases.
* gnu/packages/patches/ansible-wrap-program-hack.patch: Delete file.
* gnu/local.mk (dist_patch_DATA): Unregister it.
---
 gnu/local.mk                                  |  1 -
 gnu/packages/admin.scm                        | 38 ++++++++++++++++++-
 .../patches/ansible-wrap-program-hack.patch   | 22 -----------
 3 files changed, 36 insertions(+), 25 deletions(-)
 delete mode 100644 gnu/packages/patches/ansible-wrap-program-hack.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 0e2316a69..0d60e9b75 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -579,7 +579,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/aegisub-boost68.patch                    \
   %D%/packages/patches/agg-am_c_prototype.patch			\
   %D%/packages/patches/amule-crypto-6.patch			\
-  %D%/packages/patches/ansible-wrap-program-hack.patch		\
   %D%/packages/patches/antiword-CVE-2014-8123.patch			\
   %D%/packages/patches/antlr3-3_1-fix-java8-compilation.patch	\
   %D%/packages/patches/antlr3-3_3-fix-java8-compilation.patch	\
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 3e41b456e..ec8da6dba 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -1608,8 +1608,7 @@ of supported upstream metrics systems simultaneously.")
        (uri (pypi-uri "ansible" version))
        (sha256
         (base32
-         "1fsif2jmkrrgiawsd8r6sxrqvh01fvrmdhas0p540a6i9fby3yda"))
-       (patches (search-patches "ansible-wrap-program-hack.patch"))))
+         "1fsif2jmkrrgiawsd8r6sxrqvh01fvrmdhas0p540a6i9fby3yda"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-bcrypt" ,python-bcrypt)
@@ -1626,6 +1625,41 @@ of supported upstream metrics systems simultaneously.")
        ("python-jinja2" ,python-jinja2)
        ("python-pyyaml" ,python-pyyaml)
        ("python-paramiko" ,python-paramiko)))
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         ;; Several ansible commands (ansible-config, ansible-console, etc.)
+         ;; are just symlinks to a single ansible executable. The ansible
+         ;; executable behaves differently based on the value of
+         ;; sys.argv[0]. This does not work well with our wrap phase, and
+         ;; therefore the following two phases are required as a workaround.
+         (add-after 'unpack 'hide-wrapping
+           (lambda _
+             ;; Overwrite sys.argv[0] to hide the wrapper script from it.
+             (substitute* "bin/ansible"
+               (("import traceback" all)
+                (string-append all "
+import re
+sys.argv[0] = re.sub(r'\\.([^/]*)-real$', r'\\1', sys.argv[0])
+")))
+             #t))
+         (add-after 'wrap 'fix-symlinks
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out")))
+               (for-each
+                (lambda (subprogram)
+                  ;; The symlinks point to the ansible wrapper script. Make
+                  ;; them point to the real executable (.ansible-real).
+                  (delete-file (string-append out "/bin/.ansible-" subprogram "-real"))
+                  (symlink (string-append out "/bin/.ansible-real")
+                           (string-append out "/bin/.ansible-" subprogram "-real"))
+                  ;; The wrapper scripts of the symlinks invoke the ansible
+                  ;; wrapper script. Fix them to invoke the correct executable.
+                  (substitute* (string-append out "/bin/ansible-" subprogram)
+                    (("/bin/ansible") (string-append "/bin/.ansible-" subprogram "-real"))))
+                (list "config" "console" "doc" "galaxy"
+                      "inventory" "playbook" "pull" "vault")))
+             #t)))))
     (home-page "https://www.ansible.com/")
     (synopsis "Radically simple IT automation")
     (description "Ansible is a radically simple IT automation system.  It
diff --git a/gnu/packages/patches/ansible-wrap-program-hack.patch b/gnu/packages/patches/ansible-wrap-program-hack.patch
deleted file mode 100644
index c2e102839..000000000
--- a/gnu/packages/patches/ansible-wrap-program-hack.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-Ansible changes its behaviour depending on the name of the script that it is
-called as. Make it deal with guix' .real wrapper scripts.
-
-FIXME: Remove once wrapping ansible works properly.
-See http://lists.gnu.org/archive/html/bug-guix/2017-05/msg00015.html.
---- ansible-2.3.0.0/bin/ansible	2017-04-12 16:08:05.000000000 +0200
-+++ ansible-2.3.0.0-fixed/bin/ansible	2017-05-21 20:11:18.720872385 +0200
-@@ -75,7 +75,13 @@
-             # sometimes add that
-             target = target[:-1]
-
--        if len(target) > 1:
-+        if target[-1] == "real" and target[0].startswith('.'):
-+            target = target[:-1]
-+            target[0] = target[0][1:]
-+        if len(target) > 1 and target[1] != "real" :
-+            sub = target[1]
-+            myclass = "%sCLI" % sub.capitalize()
-+        elif len(target) > 2 and target[2] == "real" :
-             sub = target[1]
-             myclass = "%sCLI" % sub.capitalize()
-         elif target[0] == 'ansible':
-- 
2.19.2