diff --git a/guix/store.scm b/guix/store.scm index 8c774a6db2..79dcf22cca 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -797,11 +797,14 @@ signing them if SIGN? is true." (loop tail))))))) (define* (register-path path - #:key (references '()) deriver prefix) + #:key (references '()) deriver prefix + state-directory) "Register PATH as a valid store file, with REFERENCES as its list of references, and DERIVER as its deriver (.drv that led to it.) If PREFIX is not #f, it must be the name of the directory containing the new store to -initialize. Return #t on success. +initialize; if STATE-DIRECTORY is not #f, it must be a string containing the +absolute file name to the state directory of the store being initialized. +Return #t on success. Use with care as it directly modifies the store! This is primarily meant to be used internally by the daemon's build hook." @@ -809,9 +812,12 @@ be used internally by the daemon's build hook." (catch 'system-error (lambda () (let ((pipe (apply open-pipe* OPEN_WRITE %guix-register-program - (if prefix - `("--prefix" ,prefix) - '())))) + `(,@(if prefix + `("--prefix" ,prefix) + '()) + ,@(if state-directory + `("--state-directory" ,state-directory) + '()))))) (and pipe (begin (format pipe "~a~%~a~%~a~%" diff --git a/nix/guix-register/guix-register.cc b/nix/guix-register/guix-register.cc index 4aee4fde34..ed5ab23e41 100644 --- a/nix/guix-register/guix-register.cc +++ b/nix/guix-register/guix-register.cc @@ -56,10 +56,14 @@ from an existing store. It updates the new store's database with \ information about which store files are valid, and what their \ references are."; +#define GUIX_OPT_STATE_DIRECTORY 1 + static const struct argp_option options[] = { { "prefix", 'p', "DIRECTORY", 0, "Open the store that lies under DIRECTORY" }, + { "state-directory", GUIX_OPT_STATE_DIRECTORY, "DIRECTORY", 0, + "Use DIRECTORY as the state directory of the target store" }, { 0, 0, 0, 0, 0 } }; @@ -84,6 +88,15 @@ parse_opt (int key, char *arg, struct argp_state *state) break; } + case GUIX_OPT_STATE_DIRECTORY: + { + string state_dir = canonPath (arg); + + settings.nixStateDir = state_dir; + settings.nixDBPath = state_dir + "/db"; + break; + } + case ARGP_KEY_ARG: { std::ifstream *file; diff --git a/tests/guix-register.sh b/tests/guix-register.sh index 28b799b5c1..e258ec1244 100644 --- a/tests/guix-register.sh +++ b/tests/guix-register.sh @@ -79,34 +79,48 @@ guix-register -p "$new_store" < "$closure" # Doing it a second time shouldn't hurt. guix-register --prefix "$new_store" "$closure" +# Same, but with the database stored in a different place. +guix-register -p "$new_store" \ + --state-directory "$new_store/chbouib" "$closure" + # Now make sure this is recognized as valid. -NIX_STORE_DIR="$new_store_dir" -NIX_STATE_DIR="$new_store$localstatedir" -NIX_LOG_DIR="$new_store$localstatedir/log/guix" -NIX_DB_DIR="$new_store$localstatedir/guix/db" +ls -R "$new_store" +for state_dir in "$new_store$localstatedir/guix" "$new_store/chbouib" +do + NIX_STORE_DIR="$new_store_dir" + NIX_STATE_DIR="$new_store$state_dir" + NIX_LOG_DIR="$new_store$state_dir/log/guix" + NIX_DB_DIR="$new_store$state_dir/db" -export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR NIX_STATE_DIR \ - NIX_LOG_DIR NIX_DB_DIR + export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR NIX_STATE_DIR \ + NIX_LOG_DIR NIX_DB_DIR -guix-daemon --disable-chroot & -subdaemon_pid=$! -exit_hook="kill $subdaemon_pid" + guix-daemon --disable-chroot & + subdaemon_pid=$! + exit_hook="kill $subdaemon_pid" -final_name="$storedir/`basename $to_copy`" + final_name="$storedir/`basename $to_copy`" -# At this point the copy in $new_store must be valid, and unreferenced. -# The database under $new_store uses the $final_name, but we can't use -# that name in a 'valid-path?' query because 'assertStorePath' would kill -# us because of the wrong prefix. So we just list dead paths instead. -guile -c " - (use-modules (guix store)) - (define s (open-connection)) - (exit (equal? (list \"$copied\") (dead-paths s)))" + # At this point the copy in $new_store must be valid, and unreferenced. + # The database under $NIX_DB_DIR uses the $final_name, but we can't use + # that name in a 'valid-path?' query because 'assertStorePath' would kill + # us because of the wrong prefix. So we just list dead paths instead. + guile -c " + (use-modules (guix store)) + (define s (open-connection)) + (exit (equal? (list \"$copied\") (dead-paths s)))" -# When 'sqlite3' is available, check the name in the database. -if type -P sqlite3 -then - echo "select * from ValidPaths where path=\"$final_name\";" | \ - sqlite3 $NIX_DB_DIR/db.sqlite -fi + # Kill the daemon so we can access the database below (otherwise we may + # get "database is locked" errors.) + kill $subdaemon_pid + exit_hook=":" + while kill -0 $subdaemon_pid ; do sleep 0.5 ; done + + # When 'sqlite3' is available, check the name in the database. + if type -P sqlite3 + then + echo "select * from ValidPaths where path=\"$final_name\";" | \ + sqlite3 "$NIX_DB_DIR/db.sqlite" + fi +done