v0.172.0 — R-75: canonical import root, catalog-derived skeleton, import surfaces
${IMPORT_PATH} = <system namespace root>/userdata/import — ONE drop-zone per box,
on the system drive, injected at BOTH compose-env builders with NO per-drive
fallback (unresolvable leaves it unset so compose fails loudly rather than
quietly building a second, dead drop-zone).
Third BindRoot (RootImport) + Import list in BackupSpec, extended through
ValidateBackupSpec/ClassifyBinds. Load-bearing: a stale `userdata: import/<app>`
entry against the moved bind would be a WHOLE-BLOCK reject, taking the app's
mandatory hdd classification with it.
Exhaustive-root audit: resolveAbs/structuralGuard/ComputeCaptureSet/
ComputeFabBuckets now take importRoot explicitly (an import bind resolved
against hddPath would name a directory on the wrong drive); unresolvable is
refused loudly into Skipped. GetImportRoot added to both provider interfaces.
Catalog-derived skeleton: UserdataSkeleton() -> UserdataSkeletonCarry() +
BuildUserdataSkeleton(), SORTED. The carry-list makes zero-removals true by
construction (`documents` is in no catalog app but on both boxes) and is the
fresh-box floor. The sort is not tidiness: the naive map-order derivation
measured 20 distinct outputs from 20 identical runs, which with fbNeedsRecreate
is a fleet-wide FileBrowser restart loop.
One authoritative compose parser: ParseComposeUserdataMounts now delegates to
ParseComposeClassifiableBinds. Import root excluded from per-app migration.
Surfaces: FileBrowser /srv/beolvasas source; app-page "Hova tegyem a fajlokat?"
with PathEscape deep links (never QueryEscape) and class-driven copy;
data_paths: annotation with the Fork-3 asymmetry; system-owned beolvasas SMB
share refused server-side at handler AND store, button omitted in template.
Caught on the way: the sharing template's row struct was function-local, so
adding {{if .System}} would have 500'd every share row. ShareRow is now
package-level and the render test uses the handler's own type.
Tests 915 -> 949, all green. MinAgent unchanged.
This commit is contained in:
@@ -71,6 +71,24 @@
|
||||
onerror="this.style.display='none'">
|
||||
</div>
|
||||
|
||||
{{if .DataPathCards}}
|
||||
<div class="app-info-card" style="margin-top:1rem">
|
||||
<h3>Hova tegyem a fájlokat?</h3>
|
||||
<p class="form-hint">Ezeket a mappákat a Fájlkezelőben éred el. Előfordulhat, hogy először be kell jelentkezned a Fájlkezelőbe.</p>
|
||||
<div class="datapath-list">
|
||||
{{range .DataPathCards}}
|
||||
<div class="datapath-row">
|
||||
<div class="datapath-head">
|
||||
<a href="{{.Link}}" target="_blank" rel="noopener" class="datapath-link">{{.Label}} ↗</a>
|
||||
{{if .FreeSpace}}<span class="datapath-space">{{.FreeSpace}}</span>{{end}}
|
||||
</div>
|
||||
{{if .Consequence}}<p class="datapath-note">{{.Consequence}}</p>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if and .Stack.Deployed .MigrateTargets}}
|
||||
<div class="app-info-card" style="margin-top:1rem">
|
||||
<h3>Áthelyezés másik tárhelyre</h3>
|
||||
|
||||
@@ -146,11 +146,15 @@
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
{{if .System}}
|
||||
<span class="form-hint">rendszer</span>
|
||||
{{else}}
|
||||
<form method="POST" action="/sharing/shares/delete">
|
||||
{{$.CSRFField}}
|
||||
<input type="hidden" name="name" value="{{.Name}}">
|
||||
<button type="submit" class="btn btn-xs btn-danger-outline">Törlés</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
||||
@@ -1317,6 +1317,44 @@ a.stat-card:hover {
|
||||
font-size: .95rem;
|
||||
color: var(--text-1);
|
||||
}
|
||||
/* „Hova tegyem a fájlokat?" — R-75 folder rows on the app page. */
|
||||
.datapath-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: .75rem;
|
||||
}
|
||||
.datapath-row {
|
||||
border-left: 3px solid var(--blue);
|
||||
background: var(--blue-dim);
|
||||
padding: .6rem .75rem;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
.datapath-head {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: .75rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.datapath-link {
|
||||
color: var(--blue-bright);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
.datapath-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.datapath-space {
|
||||
color: var(--text-2);
|
||||
font-size: .8rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.datapath-note {
|
||||
margin: .35rem 0 0 0;
|
||||
color: var(--text-2);
|
||||
font-size: .85rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.app-info-list {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
|
||||
Reference in New Issue
Block a user