guix-register: Add '--state-directory' parameter.

* nix/guix-register/guix-register.cc (GUIX_OPT_STATE_DIRECTORY): New
  macro.
  (parse_opt): Honor it.
* tests/guix-register.sh: Add test with '--state-directory'.
* guix/store.scm (register-path): Add #:state-directory parameter.
This commit is contained in:
Ludovic Courtès 2014-07-18 11:03:50 +02:00
parent 1c00f83650
commit 689142cd75
3 changed files with 62 additions and 29 deletions

View File

@ -797,11 +797,14 @@ signing them if SIGN? is true."
(loop tail))))))) (loop tail)))))))
(define* (register-path path (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 "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 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 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 Use with care as it directly modifies the store! This is primarily meant to
be used internally by the daemon's build hook." 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 (catch 'system-error
(lambda () (lambda ()
(let ((pipe (apply open-pipe* OPEN_WRITE %guix-register-program (let ((pipe (apply open-pipe* OPEN_WRITE %guix-register-program
(if prefix `(,@(if prefix
`("--prefix" ,prefix) `("--prefix" ,prefix)
'())))) '())
,@(if state-directory
`("--state-directory" ,state-directory)
'())))))
(and pipe (and pipe
(begin (begin
(format pipe "~a~%~a~%~a~%" (format pipe "~a~%~a~%~a~%"

View File

@ -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 \ information about which store files are valid, and what their \
references are."; references are.";
#define GUIX_OPT_STATE_DIRECTORY 1
static const struct argp_option options[] = static const struct argp_option options[] =
{ {
{ "prefix", 'p', "DIRECTORY", 0, { "prefix", 'p', "DIRECTORY", 0,
"Open the store that lies under DIRECTORY" }, "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 } { 0, 0, 0, 0, 0 }
}; };
@ -84,6 +88,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
break; 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: case ARGP_KEY_ARG:
{ {
std::ifstream *file; std::ifstream *file;

View File

@ -79,34 +79,48 @@ guix-register -p "$new_store" < "$closure"
# Doing it a second time shouldn't hurt. # Doing it a second time shouldn't hurt.
guix-register --prefix "$new_store" "$closure" 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. # Now make sure this is recognized as valid.
NIX_STORE_DIR="$new_store_dir" ls -R "$new_store"
NIX_STATE_DIR="$new_store$localstatedir" for state_dir in "$new_store$localstatedir/guix" "$new_store/chbouib"
NIX_LOG_DIR="$new_store$localstatedir/log/guix" do
NIX_DB_DIR="$new_store$localstatedir/guix/db" 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 \ export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR NIX_STATE_DIR \
NIX_LOG_DIR NIX_DB_DIR NIX_LOG_DIR NIX_DB_DIR
guix-daemon --disable-chroot & guix-daemon --disable-chroot &
subdaemon_pid=$! subdaemon_pid=$!
exit_hook="kill $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. # 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 # 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 # that name in a 'valid-path?' query because 'assertStorePath' would kill
# us because of the wrong prefix. So we just list dead paths instead. # us because of the wrong prefix. So we just list dead paths instead.
guile -c " guile -c "
(use-modules (guix store)) (use-modules (guix store))
(define s (open-connection)) (define s (open-connection))
(exit (equal? (list \"$copied\") (dead-paths s)))" (exit (equal? (list \"$copied\") (dead-paths s)))"
# When 'sqlite3' is available, check the name in the database. # Kill the daemon so we can access the database below (otherwise we may
if type -P sqlite3 # get "database is locked" errors.)
then kill $subdaemon_pid
echo "select * from ValidPaths where path=\"$final_name\";" | \ exit_hook=":"
sqlite3 $NIX_DB_DIR/db.sqlite while kill -0 $subdaemon_pid ; do sleep 0.5 ; done
fi
# 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