Skip to main content

Layout

Struct Layout 

Source
pub struct Layout {
Show 13 fields pub state: PathBuf, pub repos: PathBuf, pub auth: PathBuf, pub keys: PathBuf, pub log: PathBuf, pub tls_marker: PathBuf, pub accounts: PathBuf, pub acl: PathBuf, pub public_url: PathBuf, pub seed_marker: PathBuf, pub seed_credential: PathBuf, pub followers_marker: PathBuf, pub port: u16,
}
Expand description

Where a node’s state lives, by the convention choir init writes.

Fields rather than a lookup, so a caller cannot ask for a path this does not define. The layout is deliberately not configurable file-by-file: a node whose four paths can each point somewhere else is a node whose backup, restore and status commands each need to be told all four, and every one of them is a place to get it wrong.

Fields§

§state: PathBuf

The state directory itself, ~/.choir unless told otherwise.

§repos: PathBuf

Bare repositories; the daemon’s positional root.

§auth: PathBuf

user:token, the credential the API checks.

§keys: PathBuf

Public keys the node accepts ops from. Without it the platform API stays off and every /api/* read answers 503.

§log: PathBuf

Where the daemon’s own log is appended when supervised.

§tls_marker: PathBuf

Two lines — certificate path, then key path — when this node terminates TLS itself. Its existence is the switch, the same marker discipline the review and scope gates already use: an empty file and an absent one mean opposite things, and a separate enable-flag beside the file it guards is a pair that can disagree.

§accounts: PathBuf

The D36 accounts file. Present means invites can be minted; absent means /api/accounts/invite answers 503.

§acl: PathBuf

The D29 per-repository grants. Its existence is the switch, and the daemon refuses an accounts file without one — an issued grant with no table to grade it against is a grant to everything.

§public_url: PathBuf

The one URL people outside this machine use, when there is one.

§seed_marker: PathBuf

Three key = value lines when this node is a seed of another node’s log (D80): home, credential, serve. Its existence is the switch, the same discipline as tls.enabled: a seed and a home are the same layout started with different flags, and the marker is what choir seed writes so that node serve, node install and every command after them need no seed-specific argument.

§seed_credential: PathBuf

Where choir seed keeps the user:token line the home issued, mode 0600, so the unit never points outside the state directory.

§followers_marker: PathBuf

Present when landings are pushed to each repository’s remotes (D21). Written by choir repo follower add; its existence is --followers.

§port: u16

The port to bind.

Implementations§

Source§

impl Layout

Source

pub fn new(state: &Path, port: u16) -> Layout

The standard layout under state.

Source

pub fn seed(&self) -> Option<Seed>

The home this node seeds, when it is a seed.

Source

pub fn tls(&self) -> Option<(PathBuf, PathBuf)>

The certificate and key this node terminates TLS with, if it does.

Read at start time rather than baked into the supervision file, which is what makes renewal a restart rather than a re-render: a certbot deploy hook replaces the two files and restarts the unit, and the unit still says choir node serve.

Anything but two non-empty lines is None. A half-written marker must not become a public bind with no certificate — that is invariant 9 by another route.

Source

pub fn public(&self) -> Option<String>

The public URL, when one was written.

Source

pub fn bind(&self) -> &'static str

The address the daemon should bind.

0.0.0.0 exactly when there is a certificate to present, never otherwise. The daemon refuses the unsafe combination on its own (invariant 9); this side never asks for it, so the refusal is a backstop rather than the mechanism.

Source

pub fn missing(&self) -> Vec<&Path>

What must already exist for a node to start, and does not.

Checked before the daemon is launched so the answer names choir init rather than arriving as whatever the daemon says about a path it could not read. The repository root is not in this list: the daemon creates it, and an empty node is a valid one.

A seed needs neither: it learns every key from its home’s /api/signers, and an archival seed has no readers to name. What it cannot start without is the credential its marker points at.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.