pub struct Nixos {
paths: Paths,
lock: Arc<Mutex<()>>,
budget: GcBudget,
}Fields§
§paths: Paths§lock: Arc<Mutex<()>>§budget: GcBudgetImplementations§
Source§impl Nixos
impl Nixos
Sourcefn activate_live_inner(
&self,
g: GenerationId,
op: &OpId,
slow: Option<(Duration, bool)>,
) -> Outcome
fn activate_live_inner( &self, g: GenerationId, op: &OpId, slow: Option<(Duration, bool)>, ) -> Outcome
slow (gym hooks only): the activation unit first sleeps this long,
and if uncancellable, ignores being stopped; it is the unit that is
slow, so it outlives the daemon like a real long activation.
pub fn new(paths: Paths) -> Nixos
Sourcepub fn with_budget(self, budget: GcBudget) -> Nixos
pub fn with_budget(self, budget: GcBudget) -> Nixos
The §12b bounds (services.planarian.gc).
Sourcefn profile_generations(&self) -> Vec<(u64, String)>
fn profile_generations(&self) -> Vec<(u64, String)>
The system profile’s generations: (profile number, store path).
Sourcefn prune_roots(&self, profile: &[(u64, String)], protect: &[GenerationId])
fn prune_roots(&self, profile: &[(u64, String)], protect: &[GenerationId])
Roots that no longer hold anything Planarian needs, removed before a
collection so it can free what the profile no longer keeps (§9 step 5,
§12b): a build root whose candidate is a profile generation (the
profile link roots it from commit on, and a collected one must go),
and a gen-<n> root for a generation no longer protected.
Sourcefn age_out_roots_at(&self, now: SystemTime) -> Vec<String>
fn age_out_roots_at(&self, now: SystemTime) -> Vec<String>
Build roots older than PARKING_GRACE (by the link’s own time): no
transaction can still be waiting on them, so they are a crashed or
abandoned build’s (C4).
Sourcefn plan_profile(
&self,
protect: &[GenerationId],
emergency: bool,
) -> Result<(GcPlan, Vec<(u64, String)>), Outcome>
fn plan_profile( &self, protect: &[GenerationId], emergency: bool, ) -> Result<(GcPlan, Vec<(u64, String)>), Outcome>
Plan over profile numbers. Protected generations are the profile entries whose store path is a protected generation’s.
The store path the boot menu was last installed for.
Sourcefn profile_generation(&self) -> Option<u64>
fn profile_generation(&self) -> Option<u64>
The boot menu is the one for path: as recorded after the last
successful install, or, before any (a machine installed before this
record existed), when path is the system that booted.
The number of the profile generation the profile link points at
(system-<n>-link).
fn report_path(&self) -> PathBuf
fn registry_path(&self) -> PathBuf
fn with_registry<R>( &self, f: impl FnOnce(&mut Registry) -> R, ) -> Result<R, Outcome>
fn id_of_link(&self, link: &Path) -> Result<GenerationId, Outcome>
fn override_file(&self, root: &Path) -> PathBuf
fn store_dir(&self) -> PathBuf
Sourcefn visible_files(
&self,
root: &Path,
) -> Result<(Vec<PathBuf>, Vec<String>), Outcome>
fn visible_files( &self, root: &Path, ) -> Result<(Vec<PathBuf>, Vec<String>), Outcome>
The owner’s Nix-visible files, and the untracked files left out.
Sourcefn copy_owner(&self, root: &Path) -> Result<(PathBuf, Vec<String>), Outcome>
fn copy_owner(&self, root: &Path) -> Result<(PathBuf, Vec<String>), Outcome>
Copy the owner’s visible files into a fresh directory.
fn flake_ref(&self, dir: &Path) -> String
fn staged_dir(&self, source: &Hash) -> PathBuf
fn unit_name(op: &OpId) -> String
Sourcefn lock_dir(dir: &Path) -> Result<File>
fn lock_dir(dir: &Path) -> Result<File>
§9 step 4 (I23, R11): an exclusive flock on a directory, held until
the returned handle drops. The directory itself is locked, so nothing
is added to the owner’s tree. Cooperating writers take the same lock;
one that does not is outside I23 (docs/bypasses.md, X-12).
Sourcefn lock_profile(&self) -> Result<File, Outcome>
fn lock_profile(&self) -> Result<File, Outcome>
Promote, restore and collect (the system profile and boot menu) are serialized across the daemon and the watchdog (§28, C5).
Sourcefn prune_override_store(
&self,
keep_gens: &[GenerationId],
now: SystemTime,
) -> Vec<String>
fn prune_override_store( &self, keep_gens: &[GenerationId], now: SystemTime, ) -> Vec<String>
The content-addressed override store keeps what a generation still in
the profile or protected references, the live file’s content, and
anything remembered within PARKING_GRACE (a transaction still in
flight has remembered its base and candidate but recorded neither).
Everything else goes (§28, C5). Returns the pruned hashes.
fn write_atomically(target: &Path, text: &str) -> Result<()>
Trait Implementations§
Source§impl GenerationBackend for Nixos
impl GenerationBackend for Nixos
Source§fn created_by(&self, g: GenerationId) -> Option<(u32, Timestamp)>
fn created_by(&self, g: GenerationId) -> Option<(u32, Timestamp)>
The profile link’s owner and modification time (nixos-rebuild as
root, or Planarian, which also runs as root: the journal tells those
apart; this answers for rebuilds outside Planarian).
Source§fn verify_candidate(
&self,
path: &StorePath,
nar: Option<&Hash>,
) -> Result<bool, Outcome>
fn verify_candidate( &self, path: &StorePath, nar: Option<&Hash>, ) -> Result<bool, Outcome>
C6: the store path’s contents still hash to what the store recorded
(nix-store --verify-path), and that is the NAR hash the transaction
recorded when it built the candidate. Existence alone is not enough.
Source§fn publish_boot_once(
&self,
g: GenerationId,
keep: GenerationId,
op: &OpId,
) -> Outcome
fn publish_boot_once( &self, g: GenerationId, keep: GenerationId, op: &OpId, ) -> Outcome
The boot-only path with systemd-boot (§12f): g gets its own profile
generation and boot entry, keep is made the newest profile
generation again (so the menu’s default stays keep), and the entry
for g is set to boot once (bootctl set-oneshot). All or nothing:
on any failure the profile is put back on keep’s boot menu.
Source§fn one_shot_pending(&self) -> Result<Option<GenerationId>, Outcome>
fn one_shot_pending(&self) -> Result<Option<GenerationId>, Outcome>
The pending one-shot entry, from systemd-boot’s LoaderEntryOneShot
EFI variable: nixos-generation-<n>.conf → the profile generation’s path.
fn current(&self) -> Result<GenerationId, Outcome>
fn boot_entries(&self) -> Result<Vec<GenerationId>, Outcome>
fn boot_default(&self) -> Result<GenerationId, Outcome>
fn last_booted(&self) -> Result<GenerationId, Outcome>
fn stage( &self, owner: &PinnedSource, overrides: &OverrideSet, ) -> Result<StagedSource, Outcome>
Source§fn source_hash(&self, owner: &PinnedSource) -> Result<Hash, Outcome>
fn source_hash(&self, owner: &PinnedSource) -> Result<Hash, Outcome>
Source§fn untracked(&self, owner: &PinnedSource) -> Vec<String>
fn untracked(&self, owner: &PinnedSource) -> Vec<String>
fn evaluate(&self, src: &StagedSource) -> Result<EvaluatedGeneration, Outcome>
Source§fn build(&self, eval: &EvaluatedGeneration) -> Result<Built, Outcome>
fn build(&self, eval: &EvaluatedGeneration) -> Result<Built, Outcome>
Source§fn dry_activation(&self, path: &StorePath) -> Result<ActivationPlan, Outcome>
fn dry_activation(&self, path: &StorePath) -> Result<ActivationPlan, Outcome>
fn pending_jobs(&self) -> Result<Vec<JobId>, Outcome>
Source§fn jobs_tagged(&self, op: &OpId) -> Result<Option<Vec<JobId>>, Outcome>
fn jobs_tagged(&self, op: &OpId) -> Result<Option<Vec<JobId>>, Outcome>
None: the backend cannot say whether work tagged with op exists.Source§fn override_hash(&self) -> Result<Hash, Outcome>
fn override_hash(&self) -> Result<Hash, Outcome>
Source§fn activate_live(&self, g: GenerationId, op: &OpId) -> Outcome
fn activate_live(&self, g: GenerationId, op: &OpId) -> Outcome
switch-to-configuration test.Source§fn publish_boot(&self, g: GenerationId, op: &OpId) -> Outcome
fn publish_boot(&self, g: GenerationId, op: &OpId) -> Outcome
fn protect(&self, g: GenerationId, op: &OpId) -> Outcome
fn cancel(&self, job: &JobId, op: &OpId) -> Outcome
Source§fn swap_override(&self, from: &Hash, to: &Hash, op: &OpId) -> Outcome
fn swap_override(&self, from: &Hash, to: &Hash, op: &OpId) -> Outcome
to, but only if its current hash is from. Idempotent: if it already
hashes to to, succeed without writing.Source§fn path_of(&self, g: GenerationId) -> Result<StorePath, Outcome>
fn path_of(&self, g: GenerationId) -> Result<StorePath, Outcome>
Source§fn evaluate_built(
&self,
path: &StorePath,
) -> Result<EvaluatedGeneration, Outcome>
fn evaluate_built( &self, path: &StorePath, ) -> Result<EvaluatedGeneration, Outcome>
Source§fn read_overrides(&self) -> Result<(OverrideSet, Hash), Outcome>
fn read_overrides(&self) -> Result<(OverrideSet, Hash), Outcome>
Source§fn remember_override(&self, set: &OverrideSet) -> Result<Hash, Outcome>
fn remember_override(&self, set: &OverrideSet) -> Result<Hash, Outcome>
swap_override can write it.Source§fn override_for(&self, g: GenerationId) -> Result<Option<Hash>, Outcome>
fn override_for(&self, g: GenerationId) -> Result<Option<Hash>, Outcome>
Source§fn override_content(&self, h: &Hash) -> Result<OverrideSet, Outcome>
fn override_content(&self, h: &Hash) -> Result<OverrideSet, Outcome>
remember_override kept under this hash.fn record_override(&self, g: GenerationId, hash: &Hash) -> Result<(), Outcome>
Source§fn gc_plan(
&self,
protect: &[GenerationId],
emergency: bool,
) -> Result<GcPlan, Outcome>
fn gc_plan( &self, protect: &[GenerationId], emergency: bool, ) -> Result<GcPlan, Outcome>
collect_garbage would delete now. Read-only.Source§fn space_report(&self) -> Option<SpaceReport>
fn space_report(&self) -> Option<SpaceReport>
Source§fn release_root(&self, root: &str) -> bool
fn release_root(&self, root: &str) -> bool
Source§fn age_out_build_roots(&self) -> Vec<String>
fn age_out_build_roots(&self) -> Vec<String>
Source§fn collect_garbage(
&self,
protect: &[GenerationId],
emergency: bool,
op: &OpId,
) -> Outcome
fn collect_garbage( &self, protect: &[GenerationId], emergency: bool, op: &OpId, ) -> Outcome
gc::plan), never touching
protect (I3), then collect store garbage. Mutating.