Public Access
Package the Linux desktop head as an RPM, and publish a nightly one
The third desktop platform shipped as nothing: a checkout somebody built.
VelopackUpdateChannel already named the two platforms it serves rather than
negating the one it does not, so that a Linux package would be an addition
there rather than something that had silently half-happened. This is it, and
it is deliberately not a Velopack channel.
There is no updater in the package at all. On this platform dnf is already an
updater the user trusts, audits and controls, and a second one answering to
this project instead is the capability ADR 0013 rule 4 spends a page keeping
unsettable. The cost is real and is written down rather than glossed: nothing
tells a Linux user that a newer build exists, because there is no repository
to tell them.
Rule 3 is untouched. The build job packages the release-shaped RPM on every
main build and every tag and uploads nothing, exactly as it does for Windows
and macOS; the desktop job packages the nightly-shaped one and puts it on the
rolling nightly-desktop release beside the Windows feed. Two RPMs with
different names owning different paths cannot replace one another, so rule 9's
separations come almost free here — the profile split still belongs to the
build, through DodoChannel.
vpk verifies that what it packs actually calls VelopackApp.Build().Run(), and
nothing here does that for us, so scripts/ci-linux-rpm.sh makes its own
assertions: it asks the finished package what it requires, what it provides,
what it holds and what modes those carry. Two of those checks exist because
the first realistic payload tripped them.
- .NET's libmscordbi.so links libmscordaccore.so. With bundled provides
excluded — which they must be, or this package would advertise libcoreclr
to the whole system — that produced a dependency no host on earth can
satisfy. The requires exclusion is computed from the payload rather than
listed, because a list of Microsoft's internal file names goes stale in
the direction that yields an uninstallable package.
- cp -a inherits the publish directory's modes, and off the wrong filesystem
that meant a world-writable /opt/DodoSSH: any local account able to
replace the SSH client every other account runs. For an application
holding a team's credentials in plaintext that is the trust model walked
around rather than attacked. Every mode is now set absolutely.
Verified as far as a runner can: both packages install side by side on Fedora
44, resolve webkit2gtk4.1 2.52.5 — the backend MainWindow records as measured
— keep separate launchers, icons and profiles, and dnf remove takes one tree
and leaves the other. 0.0.1~alpha.0.143 sorts below both 0.0.1 and the next
height. What no runner can answer is Phase 19, which is new and unwalked.
RHEL 9 is deliberately not claimed. It ships WebKitGTK's 4.0 line under
libwebkit2gtk-4.0.so.37, and an or-branch for it was written and then removed:
nobody has run the head there, and dnf refusing with "nothing provides
libwebkit2gtk-4.1.so.0" is a better answer than an install that draws a blank
terminal. Same sentence, and the same reason, as the missing Intel Mac.
x86_64 only, for that reason and not a different one.
This commit is contained in:
1 parent
1970e20e56
commit
1bf79c7c26
12 files changed
+1015
-5
No files matched your search
@@ -2841,3 +2841,112 @@ Register a device, sync something, then remove the application.
|
||||
**Failure means:** an empty directory is the pack id having been changed to `DodoSSH`, which puts Velopack's
|
||||
install root on top of `ClientPaths.DataDirectory` and makes an uninstall delete a user's un-synced work.
|
||||
This is the single reason the bundle is named `DodoSSH.Desktop.app`.
|
||||
|
||||
## Phase 19 — Installing the Linux client, and the things dnf does not check
|
||||
|
||||
The Linux counterpart of phases 16 and 18, and the shortest of the three because the platform takes two of
|
||||
their questions off the table. There is no updater here, so nothing in this phase asks whether an update
|
||||
arrives; and there is no signing, because nothing on this platform refuses an unsigned package — a distinct
|
||||
statement from "unsigned is fine", and `build/linux/dodossh.spec` says what stands in for a signature: the
|
||||
package comes from the project's own forge over TLS and from nowhere else.
|
||||
|
||||
What that leaves is the set nobody else can answer. **CI builds this package and installs nothing**, and
|
||||
every check in `scripts/ci-linux-rpm.sh` is a check on what the package *says* — its dependencies, its file
|
||||
list, its modes. None of them start the application, and the failures below are all of the shape "installs
|
||||
perfectly and then does not work".
|
||||
|
||||
Needs a Fedora 44 machine or newer with a graphical session. Build the package first:
|
||||
|
||||
```bash
|
||||
dotnet publish src/DodoSSH.Client.App/DodoSSH.Client.App.csproj \
|
||||
--configuration Release --runtime linux-x64 --self-contained true \
|
||||
-p:RestoreLockedMode=false --output /tmp/linux-x64
|
||||
scripts/ci-linux-rpm.sh --payload /tmp/linux-x64 --version 1.2.3 --out /tmp/rpm
|
||||
sudo dnf install /tmp/rpm/dodossh-1.2.3-1.x86_64.rpm
|
||||
```
|
||||
|
||||
### 19.1 It launches from the menu, and not only from a shell · **do this one first**
|
||||
|
||||
Log out and back in, or wait for the desktop to notice the new `.desktop` file, then start DodoSSH from the
|
||||
applications menu rather than from a terminal.
|
||||
|
||||
**Pass:** the window opens, and the running application's icon in the dock or task list is the same entry
|
||||
that launched it — one icon, not two.
|
||||
|
||||
**Failure means:** a second unlabelled icon appearing beside the launcher is `StartupWMClass` not matching
|
||||
what Avalonia sets `WM_CLASS` to. The spec sets it to `DodoSSH`, which is the assembly name and is the same
|
||||
for both channels; if Avalonia's answer has changed, `xprop WM_CLASS` on the window is what to compare
|
||||
against. Nothing at all in the menu is the desktop database not having been rebuilt — `%post` runs
|
||||
`update-desktop-database` and swallows its failure on purpose, so try it by hand before concluding anything.
|
||||
|
||||
### 19.2 The terminal draws, which is the WebKitGTK question
|
||||
|
||||
Connect to a host and use the shell: type, run something that scrolls, resize the window.
|
||||
|
||||
**Pass:** the terminal attaches within a second or two and behaves as it does on Windows.
|
||||
|
||||
**Failure means:** **a blank pane where everything else works is the known one**, and it is the reason
|
||||
`MainWindow.OnTerminalEnvironmentRequested` exists — the GTK WebView adapter in its default mode can only
|
||||
open a window of its own, so a control asked to host it in place has nothing to draw. If that method has
|
||||
stopped setting `ExperimentalOffscreen`, or the vendor has withdrawn the flag, this is what it looks like.
|
||||
A pane that reports a renderer timeout instead is the loopback WebSocket rather than the backend.
|
||||
|
||||
### 19.3 The icon is the mark, at the sizes the desktop actually asks for
|
||||
|
||||
Look at it in the applications menu, in the dock, and in the window switcher.
|
||||
|
||||
**Pass:** the accent tile and the `>_` mark, filling its square, legible at the small end.
|
||||
|
||||
**Failure means:** a generic icon is `Icon=` in the desktop entry not matching an installed file name — both
|
||||
are the package's binary name, so they can only disagree if one was edited. A blurry small icon is the
|
||||
48-pixel file missing and the 256 being scaled down; `dodossh-icon.ps1` draws four sizes and the spec
|
||||
installs four.
|
||||
|
||||
### 19.4 The passphrase is asked for, and no device key is offered
|
||||
|
||||
Open the security settings page.
|
||||
|
||||
**Pass:** registering a device key is **not** offered, and unlocking asks for the passphrase every time.
|
||||
|
||||
**Failure means:** being offered it is `DesktopDeviceKeyStores.ForThisMachine` having returned something
|
||||
other than `UnavailableDeviceKeyStore` on a platform with nothing to back it. Accepting the offer would put
|
||||
a wrap on the server that nothing can ever open.
|
||||
|
||||
### 19.5 The nightly installs beside the release rather than over it
|
||||
|
||||
With the release package installed, install the nightly one too.
|
||||
|
||||
**Pass:** `dnf` installs it as a second package rather than as an upgrade. Both entries appear in the menu,
|
||||
named *DodoSSH* and *DodoSSH Nightly*. Both run at once. Signing into the nightly asks for the passphrase
|
||||
again and appears on the account as a separate device.
|
||||
|
||||
**Failure means:** `dnf` offering to *upgrade* rather than install is the two packages sharing a name. A
|
||||
nightly that opens the release's vault already unlocked is the profile separation gone — that comes from
|
||||
`DodoChannel=nightly` reaching `ClientPaths`, not from the packaging, so check
|
||||
`~/.local/share/dodossh.nightly` exists rather than looking at the spec.
|
||||
|
||||
### 19.6 Nothing in the installed tree is writable by anyone but root
|
||||
|
||||
```bash
|
||||
find /opt/DodoSSH ! -user root -o -perm -o+w
|
||||
```
|
||||
|
||||
**Pass:** no output.
|
||||
|
||||
**Failure means:** any line here is a local account being able to replace the SSH client every other account
|
||||
on the machine runs, which for an application holding a team's credentials in plaintext is the whole trust
|
||||
model walked around rather than attacked. `ci-linux-rpm.sh` refuses to produce such a package and the spec
|
||||
sets every mode absolutely, so a hit here means one of those two was changed — it cannot arrive by accident
|
||||
from a publish directory.
|
||||
|
||||
### 19.7 Removing it leaves the vault, and leaves the other channel alone
|
||||
|
||||
Register a device, sync something, then `sudo dnf remove dodossh`.
|
||||
|
||||
**Pass:** `~/.local/share/dodossh` still holds the cache and the outbox. `/opt/DodoSSH` is gone entirely.
|
||||
`/opt/DodoSSH.Nightly` and its menu entry are untouched.
|
||||
|
||||
**Failure means:** a missing cache is `ClientPaths` having been pointed somewhere under `/opt`, which would
|
||||
make an uninstall delete a user's un-synced work — the Linux spelling of the mistake ADR 0013 decision 2
|
||||
exists to prevent. Files left behind under `/opt/DodoSSH` are files the package did not own, which means
|
||||
something wrote into the install directory at runtime and would survive a reinstall.
|
||||
Reference in new issue
Block a user