| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
pipe sources get a fixed modification time, so rsync's quick check took
changed output of the same size, e.g. a new commit hash or token, for
unchanged, and didn't deliver it. pipe sources get synced comparing
checksums now.
An edge case changes a pipe source's output without changing its size.
|
| |
|
|
|
|
|
|
|
|
|
| |
Generated flakes got locked with a bare nix flake lock in their directory,
and writeDeploy deployed them by their path. Nix takes both for the
enclosing Git work tree, if the target directory lies in one, e.g. a home
directory kept in Git, and fails, because generated flakes aren't tracked
there. Both refer to generated flakes as path: now.
An edge case deploys into a Git work tree, and the deploy test covers
deploying generated flakes.
|
| |
|
|
|
|
|
|
|
| |
Generated flakes declared every source they draw inputs from as a flake,
so drawing an input declared with flake = false from a source without
flake.nix failed, although the README says it works. Such sources get
declared with flake = false now.
An edge case draws a non-flake input from a source without flake.nix.
|
| |
|
|
|
|
|
|
|
| |
An override below an input drawn from a source that has a generated
flake itself got placed on that generated flake, which has no such
input, so Nix ignored it with a warning. Generated flakes have their
source as input of the same name, so the override goes below that.
An edge case overrides an input of a source with a generated flake.
|
| |
|
|
|
|
|
|
|
|
| |
Populate stopped the ssh master at the end of its script, which a failure
skips. The master then stays for an hour, with its control socket gone
along with populate's temporary directory. Populate stops it on exit
now, before removing that directory.
An edge case checks that no master remains after a failing and after a
succeeding deploy.
|
| |
|
|
|
|
|
|
| |
nix-store --add-root only replaces symlinks pointing into the store, so a
symlink pointing elsewhere at the target path, e.g. one a symlink source
left there, made delivering a flake fail. Populate removes such links.
An edge case switches a symlink source to a flake source.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
rsync follows a symlink at the target path, so a source switching from the
flake or flake-input type to file, pass, passage, or pipe got written into
the store path the link points to, and one switching from the symlink
type into what that link points to, e.g. another source. Populate
removes a symlink at the target path before syncing with rsync.
The roots in .populate/flake-inputs/<name> of a source that is neither a
flake nor a flake-input source anymore get removed as well.
An edge case switches a flake source to a file source.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A flake-input source delivers an input as its own flake, which
evaluating it uses with its own lock file. Populate, however, took the
input's inputs from the parent flake's lock file: on the target, by
walking the lock file, and on the deploying machine, from the parent's
nix flake archive. That had several consequences:
- An empty follows path, which removes an input, or two inputs following
each other made the walk loop forever.
- Copying left out inputs that follow other inputs, and rejected names
through them, e.g. dep/inner where dep's inner follows another input.
- Inputs given by relative paths, e.g. path:./lib, which have no lock
entry of their own to fetch, broke fetching on the target and
flake-input sources.
- Where the parent overrides an input's inputs, the input's own lock file
pins other versions than the delivered ones.
Populate now resolves the name through the parent's lock file, follows
included and guarded against cycles, to what to fetch: a locked
reference, or the flake itself, which inputs given by relative paths are
part of. It fetches that, on the deploying machine or on the target, and
then the inputs the input's own lock file pins, using nix flake archive.
An input without a lock file comes without its inputs.
New edge cases cover lock files with empty and cyclic follows, names
through follows, the delivered closure, and relative path inputs.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A new test, edge-cases, covers paths that work but have no scenario yet:
a flake given by an indirect reference, which the target fetches by its
locked reference; a remote flake in a subdirectory; a flake in a
subdirectory drawing inputs from sources; a dirty Git work tree; a flake
whose lock file needs updating; drawing inputs from a source that isn't
a directory; nested names of missing inputs; several sources sharing one
flake; and an input locked to a path that the target has.
The deploying machine gets a registry entry for the indirect reference.
Resolving it fails if the global registry can't be downloaded, which it
can't in the VM, and disabling the global registry with flake-registry
needs flakes, so the deploying machine enables them, like any deploying
machine using indirect references does. The target doesn't, so checks
for flake support on targets still mean something.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Several weaknesses let checks pass although the feature under test is
broken:
- Nix restores fetched inputs from its fetcher cache, so evaluating a
delivered flake offline after collecting garbage succeeds even if
populate rooted none of its inputs. nix_eval uses an empty cache
directory.
- Scenarios share target directories and stores, so store paths and roots
of earlier scenarios stand in for missing ones, and uploads of flakes
never run in a passing scenario. Scenarios of the flake, flake-input,
and features tests are isolated now: they start without target
directories and with a collected store on both machines.
- Phases expecting evaluation to fail pass on any evaluation failure,
e.g. a misspelt option. Each such phase has a control now: sources
differing only in what makes evaluation fail, which must evaluate.
Further, populate runs with a time limit, so a hang fails its scenario
instead of the whole test, phases can run steps on the deploying machine
before and after, and evaluating the scenarios fails if the remote
target counts as local for whoever evaluates them.
|
| |
|
|
|
|
|
|
|
|
|
| |
nixos-rebuild deploys /etc/nixos/flake.nix instead of NIX_PATH if that
file exists, so deploying anything but a flake fails on such targets.
Without writeDeploy's flake parameter, nixos-rebuild gets --no-flake if
/etc/nixos/flake.nix exists on the build target. nixos-rebuild versions
predating flakes neither know --no-flake nor look for that file, so they
don't get it.
The deploy VM test covers targets with and without that file.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
For targets using sudo, writeDeploy runs nixos-rebuild on the target via
sudo, so --use-remote-sudo has no effect there. It only matters when
nixos-rebuild runs on a separate build target and activates the system
on the target, so writeDeploy passes it only then.
A new VM test, deploy, runs writeDeploy with a stand-in for
nixos-rebuild, which records the user it runs as, NIX_PATH, and its
arguments, for deploying flakes and other sources, with and without a
separate build target, to every kind of target.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Populate never removes what it delivered for sources that aren't
configured anymore. For flake and flake-input sources, that keeps their
garbage collector roots, so what they delivered never gets collected.
With prune, populate removes everything from the target directory that
isn't a source, except .populate, after syncing the sources. It also
removes the roots in .populate/flake-inputs of names that aren't flake or
flake-input sources, and uploads left behind by interrupted runs.
Pruning is opt-in, because the target directory may contain other things
worth keeping, or be shared by deployments with different sources.
writeDeploy, writeTest, and writeCommand pass prune on to populate.
A feature scenario deploys sources, deploys fewer without pruning, then
with pruning, and checks that the removed sources' entries and roots are
gone, while the remaining sources and .populate stay.
|
|
|
tests/default.nix provides one VM test per source type, and one for
features spanning sources. Each test runs scenarios from
tests/scenarios.nix, which cover every combination of a source type's
options, deployed to the deploying machine itself, to a remote target as
root, and to a remote target using sudo. A scenario prepares the target
directory, deploys, checks the result, and deploys and checks again.
Scenarios expecting populate to fail check its error message, or check
at evaluation time if populate is expected not to evaluate.
The deploying machine creates fixtures using tests/fixtures.sh and serves
them via HTTP and git daemon, so flakes can be fetched on the target
without further network access. Checks evaluate delivered flakes without
network access to the fixtures after collecting garbage, so they verify
that the delivered store paths are complete and rooted.
|