\Drupal\strata\Drush\Commands StrataRestoreCommands

The commands that read history back and the commands that write it over the live site.

A restore is planned before it is applied, and the plan is what the operator is shown. It carries a per-subject split - restorable, degraded, unrestorable - and the plan a confirmation applies is the same object that was printed, not a second one computed after the answer. A subject somebody changed while the plan was waiting is listed as a conflict and left alone unless the operator says otherwise, because overwriting an edit nobody reviewed is a decision rather than a detail.

A merge follows the same shape and the same rule. Its manifest is printed with both values of every key the two sides disagree about, and a strategy has to be named before any of them is decided. It covers the configuration realm alone; the other realms are captured as deltas against a parent, and merging two divergent delta chains would mean inventing values.

Archives are the same history in a portable file. An import verifies every content-addressed object against its own digest before writing it and never advances a ref, so importing history from elsewhere cannot change what this site restores to.

Summary

Methods
Properties
Constants
__construct
diff
rollback
restore
quarantine
branch
merge
export
import
No public properties found
No public constants found
value
number
flag
ref
prose
agreed
announce
bytes
moment
digest
duration
yesNo
No protected properties found
No protected constants found
exporter
importer
applyPlan
printPlan
resultList
branchRows
printMerge
printConflict
mergeList
fieldDiff
render
heldCodes
targetRung
printProblems
manifestList
engine
ledger
No private constants found

Properties

$engine

$engine : \Drupal\strata\Engine

Type

Engine

Methods

__construct()

__construct(\Drupal\strata\Engine  $engine, \Drupal\strata\Health\HealthLedgerInterface  $ledger) : mixed

Constructs the command set.

Parameters

\Drupal\strata\Engine $engine

Builds the preflight, the replayer and the restore.

\Drupal\strata\Health\HealthLedgerInterface $ledger

Holds the rung each finding code sits at, which is what a quarantine moves.

Returns

mixed —

diff()

diff(string  $commit, string|null  $other = null, array  $options = ['subject' => \self::REQ, 'limit' => 200]) : \Consolidation\OutputFormatters\StructuredData\RowsOfFields

What differs between two points in history.

Without a subject this compares which subjects each commit covers, which is the question a rollback turns on: what would appear, what would disappear, and what exists in both. With one it reconstructs that subject at both commits and compares the fields.

Parameters

string $commit

The commit to compare.

string|null $other

The commit to compare it against, or NULL for the current head.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\RowsOfFields —

One row per difference, empty when the two points agree.

rollback()

rollback(string  $commit, array  $options = ['dry-run' => false, 'limit' => 0, 'fill-degraded' => false, 'accept-conflicts' => false]) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Puts the whole site back to a commit.

The plan is printed before the confirmation, with the restorable, degraded and unrestorable split and every subject somebody has changed since the plan was built. A degraded subject is one only partly reconstructable, and it is skipped unless --fill-degraded says otherwise: writing half a node over a whole one loses data that was still there.

Parameters

string $commit

Commit id to restore to.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written, or what would be.

restore()

restore(string  $commit, string  $subjects, array  $options = ['dry-run' => false, 'fill-degraded' => false, 'accept-conflicts' => false]) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Puts named subjects back to a commit, leaving the rest of the site alone.

A subject the target commit does not cover is planned anyway and comes back unrestorable, so "that node did not exist then" is an answer rather than an error.

Parameters

string $commit

Commit id to restore to.

string $subjects

Comma-separated subject paths, such as "entity/node:42,config/system.site".

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written, or what would be.

quarantine()

quarantine(string|null  $code = null, array  $options = ['dry-run' => false, 'release' => false, 'refuse' => false]) : \Consolidation\OutputFormatters\StructuredData\RowsOfFields

Stops a finding code being treated as restorable, or lets it be again.

Quarantine sits above the ceiling an unattended run may reach, so nothing gets here without a person asking: the rung takes a restore target away, which is the thing a backup exists to provide. Called with no code it lists what is currently held.

Parameters

string|null $code

The finding code to move, or NULL to list what is quarantined.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\RowsOfFields —

One row per code, empty when nothing is quarantined.

branch()

branch(string|null  $name = null, array  $options = ['from' => \self::REQ, 'delete' => false]) : \Consolidation\OutputFormatters\StructuredData\RowsOfFields

Lists the configuration branches, or creates and removes one.

Called with no name it lists what the store holds. Called with one it cuts a branch off the trunk's tip, or off --from, and --delete removes the name while leaving every commit it pointed at in place for a prune to decide about.

A branch carries configuration and nothing else, because configuration is captured whole and every other realm is captured as deltas against a parent. Flush onto one with drush strata:flush --ref=heads/NAME.

Parameters

string|null $name

The branch name, or NULL to list what exists.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\RowsOfFields —

One row per branch, the trunk included.

merge()

merge(string  $name, array  $options = ['strategy' => \self::REQ, 'dry-run' => false]) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Merges a configuration branch back into the trunk.

The manifest is printed before the confirmation: every object the merge would write, every one it would keep, and both values of every key the two sides disagree about. A conflict stops the merge unless --strategy names what to do with it, because two people having written different answers to the same question is not something to decide by default.

Applying goes through the ordinary logical restore, so the pre-write snapshot that makes it undoable is taken whatever the options say.

Parameters

string $name

The branch to merge.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written, or what would be.

export()

export(string  $path, array  $options = ['from' => \self::REQ, 'limit' => \self::REQ]) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Writes a span of history into one portable file.

What makes the archive restorable is the closure rather than the commits: every anchor a commit resolves through, every frame those anchors and segments name, every delta parent up each chain, and every dictionary any of those frames needs. An archive missing one of them unpacks cleanly and restores nothing, so anything unreadable is recorded as a problem rather than skipped.

Parameters

string $path

Where to write. A ".gz" or ".tgz" suffix compresses the archive.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written.

import()

import(string  $path, array  $options = ['dry-run' => false]) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Loads an archive's objects into this site's store.

Every content-addressed object is checked against the digest it is filed under before it is written, so an archive that was edited or truncated is caught here rather than at the moment somebody needs the restore. The ref is never advanced and the local indexes are not rebuilt; strata:reindex does that from the objects an import has just put in place.

Parameters

string $path

The archive to read.

array $options

Command options.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written, or what would be.

value()

value(array  $options, string  $name) : string|null

Reads an option that carries a value.

A value option declares DrushCommands::REQ as its default, and Drush replaces that with the string the operator supplied or with NULL before the command body runs. A method called directly - from a test, a hook, or another command - still sees the sentinel, and both forms mean that nothing was supplied. Drush only ever passes a string, so an integer sentinel cannot be confused with a value.

Parameters

array $options

The options the command was called with.

string $name

The option name.

Returns

string|null —

The value, or NULL when none was supplied.

number()

number(array  $options, string  $name, int  $fallback) : int

Reads an option that carries a whole number.

Parameters

array $options

The options the command was called with.

string $name

The option name.

int $fallback

What to return when nothing was supplied.

Returns

int —

The value, or the fallback.

flag()

flag(array  $options, string  $name) : bool

Whether a flag was given.

Parameters

array $options

The options the command was called with.

string $name

The option name.

Returns

bool —

TRUE when the flag was supplied.

ref()

ref(array  $options) : string

The ref an option set names.

Parameters

array $options

The options the command was called with.

Returns

string —

The ref name, or the main ref when none was supplied.

prose()

prose() : \Symfony\Component\Console\Style\SymfonyStyle

The style prose is written to.

Returns

\Symfony\Component\Console\Style\SymfonyStyle —

A style over standard error.

agreed()

agreed(string  $question) : bool

Asks before doing something that removes a restore target or overwrites live data.

Drush answers this itself under --yes and --no, so a scripted run never blocks. The default is no, because the question is only ever asked about something irreversible.

Parameters

string $question

What is about to happen, phrased as a question.

Returns

bool —

TRUE to go ahead.

announce()

announce(bool  $acted, string  $summary) : void

States what a pass did, at the severity the outcome deserves.

A pass that ran and a pass that declined to run both produce a summary worth reading, and the difference between them is what an operator watching a scheduled job needs to see.

Parameters

bool $acted

TRUE when the pass did the thing it was asked to do.

string $summary

The one-line summary to print.

Returns

void —

bytes()

bytes(int  $bytes) : string

Renders a byte count at a readable scale.

Parameters

int $bytes

The count.

Returns

string —

For example "4.0 MiB".

moment()

moment(int  $microtime) : string

Renders unix microseconds as a timestamp.

Parameters

int $microtime

Microseconds since the epoch, or zero for no moment at all.

Returns

string —

An ISO-8601 timestamp, or "-".

digest()

digest(string|null  $digest) : string

Shortens a content address for a table cell.

Anything that is not a digest is returned whole, so an object key or a refusal reason passed here is readable rather than truncated to twelve characters of a path.

Parameters

string|null $digest

The digest, or NULL.

Returns

string —

The first twelve characters of a digest, the value unchanged when it is not one, or "-".

duration()

duration(float  $seconds) : string

Renders a duration.

Parameters

float $seconds

The duration.

Returns

string —

For example "1.24s".

yesNo()

yesNo(bool  $value) : string

Renders a boolean as a word.

Parameters

bool $value

The value.

Returns

string —

Either "yes" or "no".

exporter()

exporter() : \Drupal\strata\Archive\ArchiveExporter

The archive writer, built when a command asks for one.

Not a constructor argument. Building one assembles the whole store, which refuses on a site that has not chosen a key yet, and Drush answers a constructor that throws by dropping every command on the class with a debug-level line nobody sees. Losing strata:rollback because strata:export could not be built is the wrong trade at exactly the moment somebody needs it.

Returns

\Drupal\strata\Archive\ArchiveExporter —

The exporter.

importer()

importer() : \Drupal\strata\Archive\ArchiveImporter

The archive reader, built when a command asks for one.

Returns

\Drupal\strata\Archive\ArchiveImporter —

The importer.

applyPlan()

applyPlan(\Drupal\strata\Restore\RestorePlan  $plan, string  $scope, bool  $dryRun) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Prints a plan, asks about it, and applies it.

The plan handed to the restore is the one that was printed, so a subject that changed between the two is caught as a conflict rather than written silently.

Parameters

\Drupal\strata\Restore\RestorePlan $plan

The plan.

string $scope

What the restore was scoped to, as the operator expressed it.

bool $dryRun

TRUE to stop after printing.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

What was written, or what would be.

printPlan()

printPlan(\Drupal\strata\Restore\RestorePlan  $plan, array  $conflicts) : void

Prints a plan in full, before anything acts on it.

Parameters

\Drupal\strata\Restore\RestorePlan $plan

The plan.

array $conflicts

Subjects changed since the plan was built.

Returns

void —

resultList()

resultList(\Drupal\strata\Restore\RestorePlan  $plan, \Drupal\strata\Restore\RestoreResult  $result) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Turns a plan and its outcome into the command's result.

Parameters

\Drupal\strata\Restore\RestorePlan $plan

The plan.

\Drupal\strata\Restore\RestoreResult $result

What the restore did.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

The result.

branchRows()

branchRows(array  $branches) : array<string,array<string,string>>

Turns a branch listing into the command's rows.

Parameters

array $branches

Branch name keyed to the branch.

Returns

array> —

Branch name keyed to its row.

printMerge()

printMerge(\Drupal\strata\Branch\MergePlan  $plan) : void

Prints a merge manifest in full, before anything acts on it.

Parameters

\Drupal\strata\Branch\MergePlan $plan

The plan.

Returns

void —

printConflict()

printConflict(\Drupal\strata\Branch\MergeEntry  $entry) : void

Prints both values of every key one object disagrees about.

Parameters

\Drupal\strata\Branch\MergeEntry $entry

The conflicting entry.

Returns

void —

mergeList()

mergeList(\Drupal\strata\Branch\MergeResult  $result) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Turns a merge outcome into the command's result.

Parameters

\Drupal\strata\Branch\MergeResult $result

What the merge did.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

The result.

fieldDiff()

fieldDiff(string  $left, string  $right, string  $subject, int  $limit) : array<string,array<string,string>>

The field-level difference for one subject between two commits.

Parameters

string $left

The commit to compare.

string $right

The commit to compare it against.

string $subject

Subject path.

int $limit

Most fields to report.

Returns

array> —

Field name keyed to its row.

render()

render(mixed  $value) : string

Renders a field value for a table cell.

Parameters

mixed $value

The value, or NULL when the field was absent.

Returns

string —

A single-line rendering, truncated to keep the table readable.

heldCodes()

heldCodes() : array<string,array<string,string|int>>

Every finding code sitting above the ceiling an unattended run may reach.

Returns

array> —

Code keyed to its row.

targetRung()

targetRung(string  $from, array  $options) : string

The rung a quarantine command is asking for.

Parameters

string $from

The rung the code sits at now.

array $options

Command options.

Returns

string —

The rung to move to.

printProblems()

printProblems(\Drupal\strata\Archive\ArchiveManifest  $manifest) : void

Prints whatever an archive could not account for.

Parameters

\Drupal\strata\Archive\ArchiveManifest $manifest

The manifest.

Returns

void —

manifestList()

manifestList(string  $path, \Drupal\strata\Archive\ArchiveManifest  $manifest) : \Consolidation\OutputFormatters\StructuredData\PropertyList

Turns a manifest into the command's result.

Parameters

string $path

The archive path.

\Drupal\strata\Archive\ArchiveManifest $manifest

The manifest.

Returns

\Consolidation\OutputFormatters\StructuredData\PropertyList —

The result.