Skip to main content

Module install

Module install 

Source
Expand description

xtask install: put the data files the scheduler catalog needs where services/CATALOG.md says they go: the unit, its configuration, the shipped catalog and the polkit policy.

It copies those four files and nothing else. It installs no binaries (a package does that; cargo install alone puts scxcli in ~/.cargo/bin, not where the policy names it), never builds, never calls systemctl, and never touches a running unit, so it works in a package build with --destdir as well as on a live machine.

The runtime layout is not relocatable: scx_catalog reads /usr/share/scx/catalog.json, the unit reads /etc/default/scx, and scxtui expects scxcli at the path the policy names, /usr/bin/scxcli. So those paths are fixed here too, and only the directories that vary between distributions (the systemd unit directory and the polkit actions directory) can be set. The policy is installed verbatim; the install checks that every action in it still names the fixed path, since a policy that named another path would make every change in scxtui ask for a password.

Re-exportsΒ§

use std::fs; πŸ”’
use std::io::Write; πŸ”’
use std::os::unix::fs::DirBuilderExt; πŸ”’
use std::os::unix::fs::OpenOptionsExt; πŸ”’
use std::os::unix::fs::PermissionsExt; πŸ”’
use std::path::Path; πŸ”’
use std::path::PathBuf; πŸ”’
use std::sync::atomic::AtomicU64; πŸ”’
use std::sync::atomic::Ordering; πŸ”’
use anyhow::Context; πŸ”’
use anyhow::Result; πŸ”’
use anyhow::bail; πŸ”’
use cargo_metadata::MetadataCommand; πŸ”’
use clap::Args; πŸ”’

StructsΒ§

InstallArgs
Item πŸ”’
One file to write: its contents, read up front, its final path and its mode.
Layout πŸ”’
The installed layout, as final paths (without DESTDIR).
Sources πŸ”’
The files in the repository that get installed.

ConstantsΒ§

CATALOG_PATH πŸ”’
scx_catalog::catalog::SHIPPED_PATH.
CONFIG_PATH πŸ”’
EnvironmentFile= of services/scx.service.
POLICY_PATH_KEY πŸ”’
SCXCLI_PATH πŸ”’
Where the contract puts scxcli, and what every action in the policy must name.

FunctionsΒ§

check_policy πŸ”’
Every <action> in the policy must carry exactly one exec.path annotation naming the fixed scxcli path, and there must be at least one action. pkexec matches an action on that path, so an action without one, or with another, is not covered by the contract.
checked_dir πŸ”’
A directory the install writes under must be absolute and plain: no . or .., so joining it under DESTDIR cannot leave DESTDIR, and no empty segments. The string is checked, not the normalised components, so /usr/./lib is refused as written rather than silently cleaned.
confine πŸ”’
Refuses a directory that resolves, symlinks followed, to outside root. Both are canonicalised, so a root given through a symlink of its own is compared by where it really is.
ensure_dir πŸ”’
Creates the missing directories of dir, each 0700 at creation and widened to 0755 once it exists, so the mode does not depend on the umask (mkdir applies it to the requested mode: under 077 a 0755 request yields 0700, and scxcli list as a user could not read /usr/share/scx). Directories that already exist are left as they are, whatever their mode: those are the administrator’s.
entry_exists πŸ”’
Whether anything is at the path: a file, a directory, or a symlink whether or not its target exists. Path::exists follows the link and would call a dangling one absent, and the rename would then replace the administrator’s link with a file.
install_bytes πŸ”’
Writes a fresh temporary file beside the target and renames it over the target. The temporary is created with create_new, so it never opens an existing file or follows a symlink, under a name unique to this process and call, so two installs do not share it; it starts at 0600 whatever the umask and gets its mode before the rename, so there is no moment at which another user can write what root will install. A failed write removes the temporary and leaves the old file whole.
install_command
prepare πŸ”’
Reads every source and checks the policy before anything is written, so a missing file or a wrong policy fails with nothing changed.
write_all πŸ”’