database: Allow for deterministic database construction.

Fixes <https://bugs.gnu.org/21073>.

* guix/store/database.scm (sqlite-register): Add #:time.
(%epoch): New variable.
(register-items): Add #:registration-time.  Pass #:time to
'sqlite-register'.
* gnu/build/install.scm (register-closure): Pass #:registration-time.
This commit is contained in:
Ludovic Courtès 2018-06-08 00:00:47 +02:00
parent 078c2329c0
commit eb9fe97495
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 17 additions and 5 deletions

View File

@ -158,6 +158,7 @@ deduplicates files common to CLOSURE and the rest of PREFIX."
#:prefix prefix #:prefix prefix
#:deduplicate? deduplicate? #:deduplicate? deduplicate?
#:reset-timestamps? reset-timestamps? #:reset-timestamps? reset-timestamps?
#:registration-time %epoch
#:schema schema))) #:schema schema)))
(define* (populate-single-profile-directory directory (define* (populate-single-profile-directory directory

View File

@ -39,6 +39,7 @@
sqlite-register sqlite-register
register-path register-path
register-items register-items
%epoch
reset-timestamps)) reset-timestamps))
;;; Code for working with the store database directly. ;;; Code for working with the store database directly.
@ -160,19 +161,22 @@ ids of items referred to."
references))) references)))
(define* (sqlite-register db #:key path (references '()) (define* (sqlite-register db #:key path (references '())
deriver hash nar-size) deriver hash nar-size time)
"Registers this stuff in DB. PATH is the store item to register and "Registers this stuff in DB. PATH is the store item to register and
REFERENCES is the list of store items PATH refers to; DERIVER is the '.drv' REFERENCES is the list of store items PATH refers to; DERIVER is the '.drv'
that produced PATH, HASH is the base16-encoded Nix sha256 hash of that produced PATH, HASH is the base16-encoded Nix sha256 hash of
PATH (prefixed with \"sha256:\"), and NAR-SIZE is the size in bytes PATH after PATH (prefixed with \"sha256:\"), and NAR-SIZE is the size in bytes PATH after
being converted to nar form. being converted to nar form. TIME is the registration time to be recorded in
the database or #f, meaning \"right now\".
Every store item in REFERENCES must already be registered." Every store item in REFERENCES must already be registered."
(let ((id (update-or-insert db #:path path (let ((id (update-or-insert db #:path path
#:deriver deriver #:deriver deriver
#:hash hash #:hash hash
#:nar-size nar-size #:nar-size nar-size
#:time (time-second (current-time time-utc))))) #:time (time-second
(or time
(current-time time-utc))))))
;; Call 'path-id' on each of REFERENCES. This ensures we get a ;; Call 'path-id' on each of REFERENCES. This ensures we get a
;; "non-NULL constraint" failure if one of REFERENCES is unregistered. ;; "non-NULL constraint" failure if one of REFERENCES is unregistered.
(add-references db id (add-references db id
@ -232,15 +236,21 @@ be used internally by the daemon's build hook."
#:reset-timestamps? reset-timestamps? #:reset-timestamps? reset-timestamps?
#:schema schema)) #:schema schema))
(define %epoch
;; When it all began.
(make-time time-utc 0 1))
(define* (register-items items (define* (register-items items
#:key prefix state-directory #:key prefix state-directory
(deduplicate? #t) (deduplicate? #t)
(reset-timestamps? #t) (reset-timestamps? #t)
registration-time
(schema (sql-schema))) (schema (sql-schema)))
"Register all of ITEMS, a list of <store-info> records as returned by "Register all of ITEMS, a list of <store-info> records as returned by
'read-reference-graph', in the database under PREFIX/STATE-DIRECTORY. ITEMS 'read-reference-graph', in the database under PREFIX/STATE-DIRECTORY. ITEMS
must be in topological order (with leaves first.) If the database is must be in topological order (with leaves first.) If the database is
initially empty, apply SCHEMA to initialize it." initially empty, apply SCHEMA to initialize it. REGISTRATION-TIME must be the
registration time to be recorded in the database; #f means \"now\"."
;; Priority for options: first what is given, then environment variables, ;; Priority for options: first what is given, then environment variables,
;; then defaults. %state-directory, %store-directory, and ;; then defaults. %state-directory, %store-directory, and
@ -284,7 +294,8 @@ initially empty, apply SCHEMA to initialize it."
#:deriver (store-info-deriver item) #:deriver (store-info-deriver item)
#:hash (string-append "sha256:" #:hash (string-append "sha256:"
(bytevector->base16-string hash)) (bytevector->base16-string hash))
#:nar-size nar-size) #:nar-size nar-size
#:time registration-time)
(when deduplicate? (when deduplicate?
(deduplicate real-file-name hash #:store store-dir)))) (deduplicate real-file-name hash #:store store-dir))))