~ruther/guix-local

689142cd759457f375230a00dc719ddc00dc2fe4 — Ludovic Courtès 11 years ago 1c00f83
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.
3 files changed, 67 insertions(+), 34 deletions(-)

M guix/store.scm
M nix/guix-register/guix-register.cc
M tests/guix-register.sh
M guix/store.scm => guix/store.scm +11 -5
@@ 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~%"

M nix/guix-register/guix-register.cc => nix/guix-register/guix-register.cc +13 -0
@@ 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;

M tests/guix-register.sh => tests/guix-register.sh +43 -29
@@ 79,34 79,48 @@ guix-register -p "$new_store" < "$closure"
# Doing it a second time shouldn't hurt.
guix-register --prefix "$new_store" "$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"

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"
# Same, but with the database stored in a different place.
guix-register -p "$new_store" \
    --state-directory "$new_store/chbouib" "$closure"

final_name="$storedir/`basename $to_copy`"
# Now make sure this is recognized as valid.

# 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)))"

# 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
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

    guix-daemon --disable-chroot &
    subdaemon_pid=$!
    exit_hook="kill $subdaemon_pid"

    final_name="$storedir/`basename $to_copy`"

    # 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)))"

    # 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