aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (test-challenge)
  #:use-module (guix tests)
  #:use-module (guix tests http)
  #:use-module ((gcrypt hash) #:prefix gcrypt:)
  #:use-module (guix store)
  #:use-module (guix monads)
  #:use-module (guix derivations)
  #:use-module (guix serialization)
  #:use-module (guix packages)
  #:use-module (guix gexp)
  #:use-module (guix base32)
  #:use-module (guix narinfo)
  #:use-module (guix scripts challenge)
  #:use-module ((guix build utils) #:select (find-files))
  #:use-module (gnu packages bootstrap)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:use-module (srfi srfi-64)
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs io ports)
  #:use-module (ice-9 match))

(define query-path-hash*
  (store-lift query-path-hash))

(define (query-path-size item)
  (mlet %store-monad ((info (query-path-info* item)))
    (return (path-info-nar-size info))))

(define* (call-with-derivation-narinfo* drv thunk hash)
  (lambda (store)
    (with-derivation-narinfo drv (sha256 => hash)
      (values (run-with-store store (thunk)) store))))

(define-syntax with-derivation-narinfo*
  (syntax-rules (sha256 =>)
    ((_ drv (sha256 => hash) body ...)
     (call-with-derivation-narinfo* drv
       (lambda () body ...)
       hash))))


(test-begin "challenge")

(test-assertm "no discrepancies"
  (let ((text (random-text)))
    (mlet* %store-monad ((drv (gexp->derivation "something"
                                                #~(call-with-output-file
                                                      #$output
                                                    (lambda (port)
                                                      (display #$text port)))))
                         (out -> (derivation->output-path drv)))
      (mbegin %store-monad
        (built-derivations (list drv))
        (mlet %store-monad ((hash (query-path-hash* out)))
          (with-derivation-narinfo* drv (sha256 => hash)
            (>>= (compare-contents (list out) (%test-substitute-urls))
                 (match-lambda
                   ((report)
                    (return
                     (and (string=? out (comparison-report-item report))
                          (bytevector=?
                           (comparison-report-local-sha256 report)
                           hash)
                          (comparison-report-match? report))))))))))))

(test-assertm "one discrepancy"
  (let ((text (random-text)))
    (mlet* %store-monad ((drv (gexp->derivation "something"
                                                #~(call-with-output-file
                                                      #$output
                                                    (lambda (port)
                                                      (display #$text port)))))
                         (out -> (derivation->output-path drv)))
      (mbegin %store-monad
        (built-derivations (list drv))
        (mlet* %store-monad ((hash (query-path-hash* out))
                             (wrong-hash
                              -> (let* ((w (bytevector-copy hash))
                                        (b (bytevector-u8-ref w 0)))
                                   (bytevector-u8-set! w 0
                                                       (modulo (+ b 1) 128))
                                   w)))
          (with-derivation-narinfo* drv (sha256 => wrong-hash)
            (>>= (compare-contents (list out) (%test-substitute-urls))
                 (match-lambda
                   ((report)
                    (return
                     (and (string=? out (comparison-report-item (pk report)))
                          (eq? 'mismatch (comparison-report-result report))
                          (bytevector=? hash
                                        (comparison-report-local-sha256
                                         report))
                          (match (comparison-report-narinfos report)
                            ((bad)
                             (bytevector=? wrong-hash
                                           (narinfo-hash->sha256
                                            (narinfo-hash bad))))))))))))))))

(test-assertm "inconclusive: no substitutes"
  (mlet* %store-monad ((drv  (gexp->derivation "foo" #~(mkdir #$output)))
                       (out -> (derivation->output-path drv))
                       (_    (built-derivations (list drv)))
                       (hash (query-path-hash* out)))
    (>>= (compare-contents (list out) (%test-substitute-urls))
         (match-lambda
           ((report)
            (return
             (and (string=? out (comparison-report-item report))
                  (comparison-report-inconclusive? report)
                  (null? (comparison-report-narinfos report))
                  (bytevector=? (comparison-report-local-sha256 report)
                                hash))))))))

(test-assertm "inconclusive: no local build"
  (let ((text (random-text)))
    (mlet* %store-monad ((drv (gexp->derivation "something"
                                                #~(list #$output #$text)))
                         (out -> (derivation->output-path drv))
                         (hash -> (gcrypt:sha256 #vu8())))
      (with-derivation-narinfo* drv (sha256 => hash)
        (>>= (compare-contents (list out) (%test-substitute-urls))
             (match-lambda
               ((report)
                (return
                 (and (string=? out (comparison-report-item report))
                      (comparison-report-inconclusive? report)
                      (not (comparison-report-local-sha256 report))
                      (match (comparison-report-narinfos report)
                        ((narinfo)
                         (bytevector=? (narinfo-hash->sha256
                                        (narinfo-hash narinfo))
                                       hash))))))))))))
(define (make-narinfo item size hash)
  (format #f "StorePath: ~a
Compression: none
URL: nar/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
NarSize: ~d
NarHash: sha256:~a
References: ~%" item size (bytevector->nix-base32-string hash)))

(define (call-mismatch-test proc)
  "Pass PROC a <comparison-report> for a mismatch and return its return
value."

  ;; Pretend we have two different results for the same store item, ITEM, with
  ;; "/bin/guile" differing between the two nars.
  (mlet* %store-monad
      ((drv1 (package->derivation %bootstrap-guile))
       (drv2 (gexp->derivation
              "broken-guile"
              (with-imported-modules '((guix build utils))
                #~(begin
                    (use-modules (guix build utils))
                    (copy-recursively #$drv1 #$output)
                    (chmod (string-append #$output "/bin/guile")
                           #o755)
                    (call-with-output-file (string-append
                                            #$output
                                            "/bin/guile")
                      (lambda (port)
                        (display "corrupt!" port)))))))
       (out1 -> (derivation->output-path drv1))
       (out2 -> (derivation->output-path drv2))
       (item -> (string-append (%store-prefix) "/"
                               (bytevector->nix-base32-string
                                (random-bytevector 32))
                               "-foo"
                               (number->string (current-time) 16))))
    (mbegin %store-monad
      (built-derivations (list drv1 drv2))
      (mlet* %store-monad ((size1 (query-path-size out1))
                           (size2 (query-path-size out2))
                           (hash1 (query-path-hash* out1))
                           (hash2 (query-path-hash* out2))
                           (nar1 -> (call-with-bytevector-output-port
                                     (lambda (port)
                                       (write-file out1 port))))
                           (nar2 -> (call-with-bytevector-output-port
                                     (lambda (port)
                                       (write-file out2 port)))))
        (parameterize ((%http-server-port 9000))
          (with-http-server `((200 ,(make-narinfo item size1 hash1))
                              (200 ,nar1))
            (parameterize ((%http-server-port 9001))
              (with-http-server `((200 ,(make-narinfo item size2 hash2))
                                  (200 ,nar2))
                (mlet* %store-monad ((urls -> (list (%local-url 9000)
                                                    (%local-url 9001)))
                                     (reports (compare-contents (list item)
                                                                urls)))
                  (pk 'report reports)
                  (return (proc (car reports))))))))))))

(test-assertm "differing-files"
  (call-mismatch-test
   (lambda (report)
     (equal? (differing-files report) '("/bin/guile")))))

(test-assertm "call-with-mismatches"
  (call-mismatch-test
   (lambda (report)
     (call-with-mismatches
      report
      (lambda (directory1 directory2)
        (let* ((files1 (find-files directory1))
               (files2 (find-files directory2))
               (files  (map (cute string-drop <> (string-length directory1))
                            files1)))
          (and (equal? files
                       (map (cute string-drop <> (string-length directory2))
                            files2))
               (equal? (remove (lambda (file)
                                 (file=? (string-append directory1 "/" file)
                                         (string-append directory2 "/" file)))
                               files)
                       '("/bin/guile")))))))))

(test-end)

;;; Local Variables:
;;; eval: (put 'with-derivation-narinfo* 'scheme-indent-function 2)
;;; End:
d>Ludovic Courtès 2020-07-05system: Do not use "hurd-target?"....Fix the following issue, that happens during CI evaluation: In guix/gexp.scm: 782:4 19 (_ _) In guix/store.scm: 1907:12 18 (_ #<store-connection 256.99 7f3727b6de10>) 1340:2 17 (map/accumulate-builds #<store-connection 256.99 7f372…> …) In srfi/srfi-1.scm: 586:29 16 (map1 ((#<file-append #<package hurd@0.9-1.91a516…> …) …)) 586:29 15 (map1 ((#<file-append #<<parameterized> bindings:…> …) …)) 586:29 14 (map1 ((#<file-append #<package hurd@0.9-1.91a516…> …) …)) 586:17 13 (map1 ((#<<operating-system> kernel: #<<parameter…> …) …)) In guix/store.scm: 1299:8 12 (call-with-build-handler #<procedure build-accumulator…> …) 2025:24 11 (run-with-store #<store-connection 256.99 7f3727b6de10> …) In guix/gexp.scm: 785:13 10 (_ _) In guix/store.scm: 1859:8 9 (_ _) In guix/gexp.scm: 243:18 8 (_ _) In guix/store.scm: 1894:38 7 (_ #<store-connection 256.99 7f3727b6de10>) In gnu/system.scm: 1012:19 6 (_ #<store-connection 256.99 7f3727b6de10>) 634:11 5 (operating-system-services #<<operating-system> kernel:…>) 611:17 4 (hurd-default-essential-services #<<operating-system> k…>) 555:18 3 (operating-system-directory-base-entries #<<operating-s…>) 1270:18 2 (operating-system-boot-parameters-file #<<operating-sy…> …) 1225:35 1 (operating-system-boot-parameters #<<operating-system>…> …) 1225:35 0 (operating-system-boot-parameters (#<<file-system> de…>) …) gnu/system.scm:1225:35: In procedure operating-system-boot-parameters: Wrong type to apply: #f "hurd-target?" is returning false when it should return true in that context. * gnu/system.scm (operating-system-boot-parameters): Check for "hurd" target field of "os" instead of using the "hurd-target?" procedure. Mathieu Othacehe 2020-07-03services: system-service-type: Add entries support for the Hurd....When creating a disk-image using --save-provenance, "guix system describe" now works. * gnu/system.scm (operating-system-directory-base-entries): Add conditional "hurd" parameter, make "initrd" parameter conditional. (hurd-default-essential-services): Use them. (operating-system-boot-parameters-file): Only add 'initrd' when set. Jan (janneke) Nieuwenhuizen 2020-07-03system: 'read-boot-parameters' allow initrd to be missing....* gnu/system.scm (read-boot-parameters): Allow initrd to be missing. Jan (janneke) Nieuwenhuizen 2020-07-03system: 'read-boot-parameters' bugfix for multiboot....* gnu/system.scm (read-boot-parameters): Oops, only return value for multiboot-modules instead of (key value). Jan (janneke) Nieuwenhuizen 2020-06-21system: Add 'sg' and 'newgrp' to %SETUID-PROGRAMS....* gnu/system.scm (%setuid-programs): Add 'sg' and 'newgrp'. Signed-off-by: 宋文武 <iyzsong@member.fsf.org> Brice Waegeneire 2020-06-19hurd-boot: Use 'setxattr' instead of invoking settrans....Note: Using `getxattr' on the Hurd instead of running showtrans does not work (yet?). * gnu/build/hurd-boot.scm (setup-translator): Use 'setxattr' instead of invoking settrans. * gnu/system.scm (hurd-multiboot-modules): Add --x-xattr-translator-records to enable xattr-embedding of translators. Jan (janneke) Nieuwenhuizen 2020-06-09services: etc: Add '/etc/ttys' symlink for the Hurd....Reported by Vitaliy Shatrov <D0dyBo0D0dyBo0@protonmail.com> via IRC. * gnu/system.scm (operating-system-etc-service): For the Hurd, add '/etc/ttys' symlink. This fixes terminal behavior in the console by setting TERM=hurd. Jan (janneke) Nieuwenhuizen 2020-06-09system: Fix typo that breaks grub.cfg generation....* gnu/system.scm (boot-parameters->menu-entry): Delete quote to evalutate and get kernel boot parameters. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Royce Strange 2020-06-08gnu: services: Add %hurd-startup-service....This decouples startup of the Hurd from the "hurd" package, moving the RC script into SYSTEM. * gnu/packages/hurd.scm (hurd)[inputs]: Remove hurd-rc-script. [arguments]: Do not substitute it. Update "runsystem.sh" to parse kernel arguments and exec into --system=SYSTEM/rc. (hurd-rc-script): Move to... * gnu/services.scm (%hurd-rc-file): ...this new variable. (hurd-rc-entry): New procedure. (%hurd-startup-service): Use it in new variable. * gnu/system.scm (hurd-default-essential-services): Use it. Jan (janneke) Nieuwenhuizen 2020-06-08system: hurd: Populate services....* gnu/system/hurd.scm (%base-services/hurd): Add hurd-console-service, hurd-getty-services, guix-service. Also add sylog and loopback, needed for ... * gnu/system.scm (hurd-default-essential-services): ... add %shepherd-root-service with dependencies: %boot-service, %activation-service, user-processes, root-file-system-service, file-system-service, pam-root-service. Jan (janneke) Nieuwenhuizen 2020-06-08services: hurd: Populate system profile....* gnu/system.scm (hurd-default-essential-services): Populate profile with packages. Jan (janneke) Nieuwenhuizen 2020-06-08services: Support etc-service for the Hurd....* gnu/system.scm (operating-system-etc-service): Cater for missing nsswitch and missing sudoers-file. For the Hurd, add "login" and "motd". (hurd-default-essential-services): Add operating-system-etc-service. Jan (janneke) Nieuwenhuizen 2020-06-08system: Support activation service for the Hurd....* gnu/build/activation.scm (boot-time-system): Use "command-line" for the Hurd. * gnu/system.scm (hurd-default-essential-services): Add %boot-service and %activation-service. Jan (janneke) Nieuwenhuizen 2020-06-08system: Use 'hurd' package in label....* gnu/system.scm (kernel->boot-label): Add keyword parameter 'hurd'. If set, use it for label. (operating-system-default-label): Call with it with operating-system-hurd. Jan (janneke) Nieuwenhuizen 2020-06-08system: Add 'multiboot-modules' field to <boot-parameters>....* gnu/system.scm (<boot-parameters>)[multiboot-modules]: New field. (read-boot-parameters): Initialize it. (operating-system-multiboot-modules, hurd-multiboot-modules): New procedure. (operating-system-boot-parameters): Cater for multiboot the Hurd and initialize it; avoid initrd in that case. (operating-system-kernel-file): Cater for for Gnumach (the Hurd) besides Linux. (boot-parameters->menu-entry): Use it to support a multiboot <menu-entry>. Jan (janneke) Nieuwenhuizen 2020-06-08system: Add 'hurd' field to <operating-system>....* gnu/system.scm (<operating-system>)[hurd]: New field. * doc/guix.texi (operating-system Reference): Document 'hurd'. Jan (janneke) Nieuwenhuizen 2020-06-08system: hurd: Add hurd-default-essential-services....* gnu/system.scm (hurd-default-essential-services): New procedure. Jan (janneke) Nieuwenhuizen 2020-06-06system: 'system-linux-image-file-name' takes an optional parameter....* gnu/system.scm (system-linux-image-file-name): Make 'target' an optional parameter. Ludovic Courtès 2020-05-29bootloader: grub: Rename the btrfs-subvolume-file-name parameter....Following discussion in <https://issues.guix.gnu.org/37305>, it seems more appropriate to give the parameter a more generic name that better describes what it does. * gnu/bootloader/grub.scm (normalize-file): Rename the BTRFS-SUBVOLUME-FILE-NAME parameter to STORE-DIRECTORY-PREFIX, and always assume this argument to be a string. (eye-candy): Likewise. Default STORE-DIRECTORY-PREFIX to "". (grub-configuration-file): Likewise. * gnu/system.scm (operating-system-bootcfg): Adapt. Maxim Cournoyer 2020-05-20bootloader: grub: Allow booting from a Btrfs subvolume....* gnu/bootloader/grub.scm (strip-mount-point): Remove procedure. (normalize-file): Add procedure. (grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. When defined, prepend its value to the kernel and initrd file names, using the NORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass the BTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well. (eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along with the NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nested variables. Adjust doc. * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt. * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise. * gnu/system/file-systems.scm (btrfs-subvolume?) (btrfs-store-subvolume-file-name): New procedures. * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs subvolume file name the store resides on to the `operating-system-bootcfg' procedure, using the new BTRFS-SUBVOLUME-FILE-NAME argument. * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of subvolumes. * gnu/tests/install.scm (%btrfs-root-on-subvolume-os) (%btrfs-root-on-subvolume-os-source) (%btrfs-root-on-subvolume-installation-script) (%test-btrfs-root-on-subvolume-os): New variables. Maxim Cournoyer 2020-05-05Merge branch 'master' into core-updatesMarius Bakke 2020-05-05system: vm: Move operating-system-uuid....* gnu/system/vm.scm (operating-system-uuid): Move to ... * gnu/system.scm: ... here. Mathieu Othacehe 2020-05-02Merge branch 'master' into core-updatesMarius Bakke 2020-05-01system: Blacklist usbkbd kernel module in default kernel-arguments....This is said to avoid a race with the usbhid kernel module. See <https://issues.guix.gnu.org/35574#18>. * gnu/system.scm (%default-modprobe-blacklist): Blacklist it. Florian Pelz 2020-05-01system: Blacklist usbmouse kernel module in default kernel-arguments....This avoids a race with the bcm5974 kernel module. Fixes <https://bugs.gnu.org/35574>. * gnu/system.scm (%default-modprobe-blacklist): New variable. (<operating-system>)[kernel-arguments]: Default to ... (%default-kernel-arguments): ... this new variable. * doc/guix.texi (operating-system Reference): Document the change. Florian Pelz 2020-04-30Merge branch 'master' into core-updates... Conflicts: gnu/local.mk gnu/packages/backup.scm gnu/packages/emacs-xyz.scm gnu/packages/guile.scm gnu/packages/lisp.scm gnu/packages/openldap.scm gnu/packages/package-management.scm gnu/packages/web.scm gnu/packages/xorg.scm Marius Bakke 2020-04-26services: system: Initial entries are non-monadic....* gnu/system.scm (operating-system-directory-base-entries): Return a regular, non-monadic value. * gnu/services.scm (system-derivation): Adjust accordingly. * gnu/system/linux-container.scm (container-essential-services): Likewise. Ludovic Courtès 2020-04-26system: 'operating-system-directory-base-entries' uses 'profile'....* gnu/system.scm (operating-system-directory-base-entries): Use a declarative profile instead of 'profile-derivation'. Ludovic Courtès 2020-04-23Merge branch 'master' into core-updates... Conflicts: etc/news.scm gnu/local.mk gnu/packages/bootloaders.scm gnu/packages/linphone.scm gnu/packages/linux.scm gnu/packages/tls.scm gnu/system.scm Marius Bakke 2020-04-22system: Automatically adjust linux-module packages to use the...operating-system's kernel. * gnu/system.scm (package-for-kernel): New procedure. (operating-system-directory-base-entries): Use it. * gnu/tests/linux-module.scm: Test it. Danny Milosavljevic 2020-04-22system: Split %BASE-PACKAGES in smaller parts....* gnu/system.scm: (%base-packages-interactive, %base-packages-linux, %base-packages-networking, %base-packages-utils): New variables. (%base-packages): Use those new variables. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Brice Waegeneire 2020-04-22system: 'operating-system-boot-parameters-file' uses 'scheme-file'....* gnu/system.scm (operating-system-boot-parameters-file): Use 'scheme-file' instead of 'gexp->file'. (operating-system-directory-base-entries): Adjust accordingly. Ludovic Courtès 2020-04-21Revert "system: Don’t create a module database when no modules are available."...This reverts commit b2fff3b5de7d510fe4809e9a97089dddf2a39ffc. Fixes <https://bugs.gnu.org/40713>. Reported by pkill9 <pkill9@runbox.com>. This commit is incorrect: its effect depends on whether KERNEL's build output is already available in the store, it breaks with non-package kernels as reported at <https://bugs.gnu.org/40713>, and the LINUX-MODULE-DATABASE hook is required at all times since 5c79f238634c5adb6657f1b4b1bb4ddb8bb73ef1 removed the relevant bits from the 'linux-libre' package. Ludovic Courtès