From fe5fabcea1a2e105cad4b4d682a138333d1dfba6 Mon Sep 17 00:00:00 2001 From: Steffen Beyer Date: Wed, 1 Apr 2026 04:32:39 +0200 Subject: [PATCH] Add Go module packaging for web services --- tribes/packages/go.scm | 247 ++++++++++++++++++++++++++++++++++++++++ tribes/packages/web.scm | 114 +++++++++++++++++++ 2 files changed, 361 insertions(+) create mode 100644 tribes/packages/go.scm create mode 100644 tribes/packages/web.scm diff --git a/tribes/packages/go.scm b/tribes/packages/go.scm new file mode 100644 index 0000000..eac8bc1 --- /dev/null +++ b/tribes/packages/go.scm @@ -0,0 +1,247 @@ +(define-module (tribes packages go) + #:use-module (guix base32) + #:use-module (guix build-system gnu) + #:use-module (guix build-system trivial) + #:use-module (guix gexp) + #:use-module (guix packages) + #:use-module (guix utils) + #:use-module (gnu packages bash) + #:use-module (gnu packages base) + #:use-module (gnu packages compression) + #:use-module (gnu packages golang) + #:use-module (gnu packages nss) + #:use-module (gnu packages version-control) + #:export (fetch-go-modules + build-go-module + go-module-package)) + +(define* (fetch-go-modules source + #:key + name + version + sha256 + (go go) + (mod-root ".") + (delete-vendor? #t) + goproxy) + "Return a fixed-output store item containing the vendored Go modules for +SOURCE." + (computed-file + (string-append name "-" version "-go-modules") + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils) + (ice-9 ftw) + (ice-9 match) + (srfi srfi-1)) + + (define out #$output) + (define work (string-append (getcwd) "/build")) + (define source-item #+source) + (define source-dir (string-append work "/source")) + (define scratch-dir (string-append work "/scratch")) + (define cert-file + #$(file-append nss-certs "/etc/ssl/certs/ca-certificates.crt")) + (define certs-dir + #$(file-append nss-certs "/etc/ssl/certs")) + (define path + (string-join + (list #$(file-append go "/bin") + #$(file-append git-minimal "/bin") + #$(file-append bash-minimal "/bin") + #$(file-append coreutils "/bin") + #$(file-append findutils "/bin") + #$(file-append gzip "/bin") + #$(file-append tar "/bin") + #$(file-append unzip "/bin") + (or (getenv "PATH") "")) + ":")) + + (define (copy-directory-contents source destination) + (for-each + (lambda (entry) + (copy-recursively (string-append source "/" entry) + (string-append destination "/" entry) + #:keep-mtime? #t)) + (remove (lambda (entry) + (member entry '("." ".."))) + (scandir source)))) + + (define (unpack-archive archive destination) + (mkdir-p scratch-dir) + (with-directory-excursion scratch-dir + (cond + ((string-suffix? ".zip" archive) + (invoke "unzip" archive)) + (else + (invoke "tar" "-xf" archive))) + (let ((entries (remove (lambda (entry) + (member entry '("." ".."))) + (scandir ".")))) + (match entries + ((entry) + (if (file-is-directory? entry) + (copy-recursively entry destination #:keep-mtime? #t) + (copy-directory-contents "." destination))) + (_ + (copy-directory-contents "." destination)))))) + + (mkdir-p work) + (mkdir-p source-dir) + (if (file-is-directory? source-item) + (copy-recursively source-item source-dir #:keep-mtime? #t) + (unpack-archive source-item source-dir)) + (invoke #$(file-append coreutils "/bin/chmod") "-R" "u+w" source-dir) + + (setenv "PATH" path) + (setenv "HOME" (string-append work "/home")) + (setenv "XDG_CACHE_HOME" (string-append work "/cache")) + (setenv "GOCACHE" (string-append work "/go-cache")) + (setenv "GOMODCACHE" (string-append work "/go-mod-cache")) + (setenv "GOPATH" (string-append work "/go")) + (setenv "GO111MODULE" "on") + (setenv "GOTOOLCHAIN" "local") + (setenv "SSL_CERT_DIR" certs-dir) + (setenv "SSL_CERT_FILE" cert-file) + (setenv "GIT_SSL_CAINFO" cert-file) + (mkdir-p (getenv "HOME")) + (mkdir-p (getenv "XDG_CACHE_HOME")) + (mkdir-p (getenv "GOCACHE")) + (mkdir-p (getenv "GOMODCACHE")) + (mkdir-p (getenv "GOPATH")) + #$@(if goproxy + (list #~(setenv "GOPROXY" #$goproxy)) + '()) + + (with-directory-excursion + (if (string=? #$mod-root ".") + source-dir + (string-append source-dir "/" #$mod-root)) + (when (and #$delete-vendor? (file-exists? "vendor")) + (delete-file-recursively "vendor")) + (invoke "go" "mod" "vendor") + (mkdir-p out) + (copy-recursively "vendor" out #:keep-mtime? #t)))) + #:options + `(#:hash ,(base32 sha256) + #:hash-algo sha256 + #:recursive? #t + #:leaked-env-vars ("http_proxy" "https_proxy" + "LC_ALL" "LC_MESSAGES" "LANG" "COLUMNS")))) + +(define* (build-go-module source + #:key + name + version + home-page + synopsis + description + license + vendor-sha256 + (go go) + (mod-root ".") + (sub-packages '(".")) + (build-flags '("-trimpath")) + (ldflags '()) + (test-flags '()) + (test-sub-packages '("./...")) + (tests? #t) + (delete-vendor? #t) + goproxy + (native-inputs '()) + (inputs '())) + "Return a package that builds SOURCE with vendored Go modules." + (let* ((go-modules + (fetch-go-modules source + #:name name + #:version version + #:sha256 vendor-sha256 + #:go go + #:mod-root mod-root + #:delete-vendor? delete-vendor? + #:goproxy goproxy)) + (ldflags-string (string-join ldflags " ")) + (ldflags-arguments + (if (null? ldflags) + '() + `("-ldflags" ,ldflags-string)))) + (package + (name name) + (version version) + (source source) + (build-system gnu-build-system) + (native-inputs + (append (list go) + native-inputs)) + (inputs inputs) + (arguments + (list + #:tests? tests? + #:modules '((guix build gnu-build-system) + (guix build utils)) + #:phases + #~(modify-phases %standard-phases + (delete 'configure) + (add-after 'unpack 'install-vendor-directory + (lambda _ + (let ((vendor-directory + (if (string=? #$mod-root ".") + "vendor" + (string-append #$mod-root "/vendor")))) + (when (file-exists? vendor-directory) + (delete-file-recursively vendor-directory)) + (copy-recursively #+go-modules vendor-directory + #:keep-mtime? #t)))) + (add-before 'build 'configure-go-environment + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (setenv "HOME" (string-append (getcwd) "/.home")) + (setenv "XDG_CACHE_HOME" (string-append (getcwd) "/.cache")) + (setenv "GOCACHE" (string-append (getcwd) "/go-cache")) + (setenv "GOMODCACHE" (string-append (getcwd) "/go-mod-cache")) + (setenv "GOPATH" (string-append (getcwd) "/go")) + (setenv "GOBIN" (string-append out "/bin")) + (setenv "GO111MODULE" "on") + (setenv "GOTOOLCHAIN" "local") + (setenv "GOPROXY" "off") + (setenv "GOSUMDB" "off") + (mkdir-p (getenv "HOME")) + (mkdir-p (getenv "XDG_CACHE_HOME")) + (mkdir-p (getenv "GOCACHE")) + (mkdir-p (getenv "GOMODCACHE")) + (mkdir-p (getenv "GOPATH")) + (mkdir-p (getenv "GOBIN"))))) + (replace 'build + (lambda _ + (with-directory-excursion + (if (string=? #$mod-root ".") + "." + #$mod-root) + (for-each + (lambda (sub-package) + (apply invoke "go" "install" + (append + '#$build-flags + '#$ldflags-arguments + (list sub-package)))) + '#$sub-packages)))) + (replace 'check + (lambda _ + (when #$tests? + (with-directory-excursion + (if (string=? #$mod-root ".") + "." + #$mod-root) + (apply invoke "go" "test" + (append '("-mod=vendor") + '#$test-flags + '#$test-sub-packages)))))) + (replace 'install + (lambda _ + #t))))) + (home-page home-page) + (synopsis synopsis) + (description description) + (license license)))) + +(define go-module-package build-go-module) diff --git a/tribes/packages/web.scm b/tribes/packages/web.scm new file mode 100644 index 0000000..1eba853 --- /dev/null +++ b/tribes/packages/web.scm @@ -0,0 +1,114 @@ +(define-module (tribes packages web) + #:use-module (gnu packages) + #:use-module ((gnu packages web) #:prefix upstream:) + #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix base32) + #:use-module (guix build-system gnu) + #:use-module (guix download) + #:use-module (guix gexp) + #:use-module (guix git-download) + #:use-module (guix packages) + #:use-module (guix utils) + #:use-module (tribes packages go) + #:export (hitch + vinyl + lego)) + +(define-public hitch + (package + (inherit upstream:hitch) + (version "1.8.0") + (source + (origin + (method url-fetch) + (uri (string-append "https://hitch-tls.org/source/hitch-" + version + ".tar.gz")) + (sha256 + (base32 "0klg2pfsbhjdabjv52i0gfjfv23r45n4vs3965xa5zkzpj299jfz")))))) + +(define-public vinyl + (package + (inherit upstream:varnish) + (name "vinyl") + (home-page "https://vinyl-cache.org/") + (version "9.0.0") + (source + (origin + (method url-fetch) + (uri (string-append home-page "_downloads/vinyl-cache-" + version + ".tgz")) + (sha256 + (base32 "05xxhgs1r9zwanx5arafrd7hkjn3kmsnrbfh1zajfxm7q88c4h4p")))) + (arguments + (substitute-keyword-arguments (package-arguments upstream:varnish) + ((#:phases phases) + #~(modify-phases %standard-phases + (add-after 'unpack 'use-absolute-file-names + (lambda _ + (substitute* '("bin/vinyltest/vtc_vinyl.c" + "bin/vinyltest/vtest2/src/vtc_process.c" + "bin/vinyltest/vtest2/src/vtc_haproxy.c" + "bin/vinyltest/tests/u00014.vtc" + "bin/vinyld/mgt/mgt_vcc.c") + (("/bin/sh") (which "bash"))) + (let ((rm (which "rm"))) + (substitute* "bin/vinyld/mgt/mgt_shmem.c" + (("rm -rf") (string-append rm " -rf"))) + (substitute* "bin/vinyltest/vtest2/src/vtc_main.c" + (("/bin/rm") rm)) + (substitute* "bin/vinyld/mgt/mgt_main.c" + (("rm -rf") (string-append rm " -rf")))) + (substitute* "bin/vinyltest/tests/u00000.vtc" + (("/bin/echo") (which "echo"))))) + (add-after 'unpack 'remove-failing-tests + (lambda _ + ;; This test still trips on name resolution in the build + ;; container. + (delete-file "bin/vinyltest/tests/b00085.vtc"))) + (add-before 'install 'patch-Makefile + (lambda _ + (substitute* "Makefile" + (("^install-data-am: install-data-local") + "install-data-am: ")))) + (add-after 'install 'wrap-vinyld + ;; Vinyl uses GCC to compile VCL, so wrap it with the required + ;; toolchain environment instead of propagating GCC globally. + (lambda* (#:key inputs #:allow-other-keys) + (wrap-program (string-append #$output "/sbin/vinyld") + `("PATH" ":" prefix (,(dirname (which "as")))) + `("LIBRARY_PATH" ":" prefix + (,(dirname + (search-input-file inputs "lib/libc.so"))))))))))) + (synopsis "Web application accelerator") + (description + "Vinyl Cache is a high-performance HTTP accelerator. It acts as a +caching reverse proxy and load balancer. You install it in front of any +server that speaks HTTP and configure it to cache content through an +extensive configuration language.") + (properties + '((release-monitoring-url . "https://vinyl-cache.org/releases/"))))) + +(define-public lego + (build-go-module + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/go-acme/lego") + (commit "v4.33.0"))) + (file-name (git-file-name "lego" "4.33.0")) + (sha256 + (base32 "0627wnwbh46fsra6b3l85n3wsv91v8ghrrvw69djbl8ir5w1lmk8"))) + #:name "lego" + #:version "4.33.0" + #:vendor-sha256 "0zsfb26lrsm7ch6avm3bhh55qjfys3m66y61k12546yky865lxmb" + #:sub-packages '("./cmd/lego") + #:ldflags '("-s" "-w" "-X" "main.version=4.33.0") + #:tests? #f + #:home-page "https://go-acme.github.io/lego/" + #:synopsis "Let's Encrypt client and ACME library written in Go" + #:description + "Lego is an ACME client and library for Let's Encrypt and other ACME +certificate authorities." + #:license license:expat))