Skip to content

Releases

Nixup 0.1.6

Choose a tag to compare

@by-architect by-architect released this 08 Nov 15:48

Nixup 0.1.6

  • Request APK certificate collection on affected Android 13 builds, which otherwise return no signing
    information and reject valid downloads with an empty signer in the error. Signing-key checks remain enabled.
  • Read default-app role holders through Android's role service instead of an unavailable shell
    getter, fixing false activation failures for default apps on Android 13.

Nixup 0.1.5

Choose a tag to compare

@by-architect by-architect released this 07 Nov 15:59

Nixup 0.1.5

  • DAVx⁵'s accounts in the config: services.davx5 (Nixup's own; NixOS has no DAVx⁵, an Android app). Each build
    sets them up: an account the phone has not got opens DAVx⁵'s login screen on the phone, already filled in with the
    server, the user name and the password (passwordFile, sent to the phone root-only like every secret), so a tap on
    Login and one on Finish add it; with automatic = true it is added with no taps (the build asks the server
    for the calendars and address books itself, writes them into DAVx⁵'s database, adds the account as DAVx⁵ and starts
    its first sync), on DAVx⁵ 4.5.17 to 4.5.21, whose database Nixup knows; any other DAVx⁵ gets the login screen.
    An account there gets the config's user name and password at each build. syncCollections (all by
    default, or none) is DAVx⁵'s own setting of what it selects for syncing as it finds it, given back when
    services.davx5 leaves the config. install = "fdroid" installs DAVx⁵ too; it gets the contacts, calendar and
    notifications permissions, unrestricted battery use, and is never paused for being unused (which takes an app's
    permissions away).
  • Backups keep an app's accounts too (the new accounts part, on by default): the accounts it adds to Android's
    settings, with their passwords, user data, auth tokens, which apps see them and their sync settings (which of its
    sync adapters run, automatically, how often). Android keeps them outside the app's folders and deletes them with
    the app, so a restored DAVx⁵ had its data but no account to sync with. A restore adds the missing ones again as the
    app itself, with their sync settings: Android lets only an account type's own app add its accounts, and shows an
    account's sync settings only to a caller that can see it. One that is on the phone stays as it is. The Backups tab
    offers them among the parts to restore. Backups made before this have none: such an app is signed in again by hand
    once.
  • Backups keep which runtime permissions an app was granted, and a restore grants them again (none is taken away; the
    config's own permissions are set again by the next build).
  • A restore takes the app's files out of the backup into a folder of their own first, as Neo Backup does, and only
    then puts them in place of the app's: a restore that fails, or a restart in the middle, leaves the app's data as it
    was (before, its data was emptied first). A restore a restart broke off is picked up again after it.
  • A restored app is let off Android's stopped state, where the restore and an install leave it: Android 15 and later
    start none of its syncs or jobs until it is opened, so a restored DAVx⁵ did not sync by itself.
  • After an app is installed from a backup, its data waits (up to 30 s) for Android to have made the app's folders:
    before, it went in at once, and Android could replace the folder under it (a whole Termux restore ended in
    thousands of "no such file or directory" errors).
  • An app's device data (deviceData) is restored on phones whose kernel refuses moving files there from Nixup's own
    folder (another encryption key): it is copied instead.
  • A restore no longer relabels what links in an app's data or a folder point to: chcon followed them (Termux's
    storage/shared points at the whole shared storage).
  • Files restored into Android/data, Android/media and Android/obb get their owner and storage quota from Android's own
    storage service, where the phone's storage is FUSE.
  • The link to an app's native libraries that older Androids put in its data is left out of backups and never
    replaced by a restore, as Neo Backup does.

Nixup 0.1.2

Choose a tag to compare

@by-architect by-architect released this 07 Nov 08:18

Nixup 0.1.2

  • nixup-rebuild on the phone, as nixos-rebuild on NixOS (as root, in adb's shell, the app's terminal or ssh):
    nixup-rebuild switch builds the config the app picked, dry-activate says what would change, switch --upgrade
    takes everything at its newest, switch --rollback goes back a generation, list-generations lists them;
    --file and --flake build another config this once, --specialisation picks one.
  • nixup-config create, on a PC: a phone's config made from what the phone has now (its settings, its apps and the
    repository each comes from, the apps it came with that are removed or disabled, battery and default apps), as
    nixos-generate-config does for a NixOS machine, checked against Nixup's options before it is written.
  • On a PC, nixup-rebuild lists the phones adb sees (over USB and the network) and asks which one, and can connect
    one over the network (pairing with Wireless debugging when the phone asks); with no terminal, it takes the only one.
  • nixup-version is the system's version command now; nixos-version stays, the same command, for tools written
    for NixOS.
  • A dry run takes another config (build.sh dry --source=…): before, it dry-ran the picked config instead.
  • A build from a PC over ssh (nixup-rebuild --target-host <phone>, as a Matrix-style flake does) works: from Nixup's
    sshd the engine got none of Android's runtime variables, ran nothing and still "succeeded", so the build was kept
    as a generation without its packages, /etc or services (the shells then said "set-environment: No such file"),
    and the store's roots were emptied for the next clean-up to take what the phone used. The scripts now take those
    variables from Android itself, a build stops when the engine did not run, and the roots stay as they were then.
    A phone built that way builds again once to put it right.
  • One /tmp for every service and every session, as on NixOS: a user's tmux server started by a service is the one
    their ssh sessions reach. serviceConfig.PrivateTmp = true (and DynamicUser) gives a service its own.

Nixup 0.1.1 BETA

Choose a tag to compare

@by-architect by-architect released this 07 Nov 05:28

Nixup 0.1.1 BETA

  • Password logins over SSH work: with services.openssh.settings.PasswordAuthentication = true sshd checks a
    user's password through PAM, as on NixOS (UsePAM is on by itself then; pam_unix reads the view's /etc/shadow).
    Without PAM, nixpkgs' OpenSSH could only check DES passwords, so no NixOS-style hash ever matched.

  • Users' passwords, as on NixOS: users.users.<name>.hashedPassword, password (hashed on the phone),
    hashedPasswordFile (a file from the config's folder, put on the phone readable by root alone, or one already
    there), initialPassword and initialHashedPassword, in the view's /etc/shadow, which sshd takes for a
    password login; expires (no logins from that day on). Also enable = false (the user is left out),
    linger = false (its own units do not run), subUidRanges, subGidRanges and autoSubUidGidRange
    (/etc/subuid, /etc/subgid), users.defaultUserHome and users.manageLingering, with NixOS's checks and
    warnings.

  • A new phone builds again: today's nixos-unstable dropped a NixOS module Nixup imported (security/dhparams.nix),
    which stopped every first build; Nixup now takes only the modules the nixpkgs has, and evaluates a
    configuration.nix with that nixpkgs' own lib (Home Manager no longer warns of a mismatch).

  • Safer by default: Nixup's folders and its /etc were writable by every user of its view (Magisk starts modules
    with umask 0), so a service's user or a build user could change what root runs; they are root's alone now, and
    an older install's are put right at the next start.

  • On Samsung phones (One UI): density and navigation go back to the phone's own when they leave the config (its
    screen resolution's density, its own navigation); settings One UI resets at each start are put back at each
    start; Quick Settings tiles it refuses are told, not shown as done; a Samsung preload that cannot be brought back
    is told as such.

  • A build in which a service, a setting or an activation script failed is still the phone's build (its services
    start at boot, its generation is kept), as NixOS's switch does, and ends failed with what did not work. A profile
    in a format the module does not know (sent by a PC with a newer Nixup) is refused before anything changes.

  • The app's New and Pick file work in Downloads; an install that waits on Google Play Protect's question says so,
    and android.settings.developer.verifyAdbApps = false is set before the installs.

  • Builds, backups and updates keep the phone awake while they run (a timer's at night no longer stops when the
    phone sleeps), and two of them at once no longer mix their files; a broken-off build is picked up after a restart
    as before, and Free up space waits for a running build.

  • Removing Nixup waits for the phone's unlock and tries again at the next start when something did not go back.
    Installing it again with the same config works at once: the apps the removal took off (their data kept) no longer
    stop the first build with "this system has no such switch"; their settings wait until the build installs them.

  • Restoring an app's backup no longer follows the links in its data: restoring Termux could empty the whole shared
    storage (its storage/shared link). Nixup never follows a link when it empties a folder (a user's in /run
    either), nor when it gives a user's folders their owner and mode.

  • unitConfig's After, Wants, Requires and the other order keys work as on NixOS, ConditionUser is
    decided when the config is built, and sockets, timers, paths and targets take restartTriggers and NixOS's other
    unit options; users.groups has NixOS's wheel, users, disk, tty and dialout.

  • A path unit can watch a path under a specifier, as systemd's: PathChanged = "%h/inbox" in a Home Manager or
    systemd.user unit is in its user's home (%t, %S, %C, %L, %E too).

  • A config whose profile is past 128 KiB (a few specialisations, or Home Manager users with many units) builds on
    the phone: it stopped with "Argument list too long".

  • A service's ExecStop that hangs is ended after TimeoutStopSec, as systemd ends it, with what it started.

  • Removing a user together with its Home Manager config is told plainly (its home is left as it is, as NixOS
    leaves it), not as a failure.

  • Users that only Nixup knows (a uid of their own) log in without "bad uid" and get their XDG_RUNTIME_DIR.

  • A user's own shell package (users.users.<name>.shell = pkgs.xonsh) is fetched: sshd refused such a user ("shell
    … does not exist") unless the same package was in environment.systemPackages.

  • NixOS's programs.* for the shells, as nixpkgs' own modules: programs.tmux, git, neovim, vim, htop,
    direnv, starship, zoxide, fzf, bat, nix-index, yazi, ssh, mosh, nushell and others, with
    environment.corePackages and environment.defaultPackages; nano and command-not-found stay off on a phone.

  • NixOS's networking.hostFiles, networking.stevenblack (nixpkgs' own module: StevenBlack's ad and tracker
    blocklist, with block and whitelist) and networking.proxy (default, httpProxy, httpsProxy,
    ftpProxy, rsyncProxy, allProxy, noProxy): the files' lines go into the /etc/hosts of Nixup's
    services and shells (Android's apps keep Android's), and the proxy into every shell session, Nix's daemon and
    the phone's own builds' downloads.

  • The shells as on NixOS, with nixpkgs' own modules: environment.shellAliases, shellInit, loginShellInit,
    interactiveShellInit, localBinInPath, homeBinInPath, shells and profiles, and programs.bash,
    programs.zsh, programs.fish and programs.xonsh with their options and plugins (bash's completion, zsh's
    autosuggestions and syntax highlighting, oh-my-zsh, ...). With Nix packages, /etc/profile, /etc/bashrc,
    /etc/zshrc, /etc/fish and /etc/set-environment are NixOS's own, the prompt is NixOS's (with the phone's name),
    and PATH is made of the profiles, as on NixOS: the user's own, /etc/profiles/per-user/<user>, root's, and
    /run/current-system/sw (system.path), with Android's commands after them. users.defaultUserShell is the
    users' shell (bash, as programs.bash makes it), and a user whose shell is zsh, fish or xonsh needs its
    programs.<shell>.enable, as on NixOS. Each user that logs in gets a /run/user/<uid> (XDG_RUNTIME_DIR).
    Without Nix packages the phone's shell stays Android's sh, with environment.variables and extraInit.

  • The system's version, as on NixOS: each generation keeps its label (system.nixos.label, with
    system.nixos.tags and the nixpkgs version) and the config's commit (system.configurationRevision), which
    the app's Generations shows; system.copySystemConfiguration = true; keeps a copy of the configuration.nix
    with each generation. nixos-version tells them (--revision, --configuration-revision, --json),
    /etc/os-release and /etc/lsb-release are in Nixup's view, and system.build.toplevel is the profile.

  • Scripts, as on NixOS: system.activationScripts run as root with each build and each start of the phone, in
    Nixup's view, before the services start (in the order their deps say; a dry run runs those with
    supportsDryActivation, with NIXOS_ACTION=dry-activate); system.preSwitchChecks run before a build changes
    anything, and one that fails stops it (NIXOS_NO_CHECK=1 leaves them out); system.userActivationScripts run
    as each normal user when they change and at each start of the phone, through NixOS's nixos-activation unit. A script's undo (Nixup's own) runs once when it
    leaves the config and when Nixup is removed, so the phone gets back what it changed. NixOS's modules that have
    activation scripts build now.

  • The phone builds its config by itself, as NixOS's system.autoUpgrade: at dates (with randomizedDelaySec,
    fixedRandomDelay and persistent) it builds again with everything at its newest (upgrade = false: as locked),
    the picked config (a git clone gets its new commits first) or flake, with channel for a configuration.nix
    alone, keeping the specialisation in use, and frees up space after (runGarbageCollection). Only on Wi-Fi unless
    android.autoUpgrade.onlyOnUnmetered = false, only while charging with android.autoUpgrade.onlyWhileCharging,
    and never on a low battery.

  • nix.buildMachines with nix.distributedBuilds, as on NixOS: a package cache.nixos.org has not got (an overlay's,
    an unfree one) is built on those machines over ssh and sent back, where the build stopped at it before; the
    shells' builds go to them too (/etc/nix/machines).

  • systemd timers' FixedRandomDelay works (it was taken and did nothing).

  • Seraph is now called Nixup: the app (dev.nixup.manager), the Magisk module (nixup), its data
    (/data/adb/nixup), nixup-rebuild, nixup-play-login, nixup-shell, nixup-backup, and the flake
    (github:by-architect/Nixup, nixup.lib.nixupSystem, nixupConfigurations). Installing Nixup takes a
    Seraph install over, as Seraph took Andronix's: its data moves (with a link left at /data/adb/seraph, so
    paths a config names there still work), its module and app go, and its config stays where it is. Allow the
    Nixup app root when it asks. A flake made for Seraph (seraph.lib.seraphSystem, seraphConfigurations)
    and androidApp = "dev.seraph.manager" build as they are.

  • Nix in the phone's shells (the app's terminal, ssh, su -c nixup-shell), as on NixOS: nix shell nixpkgs#htop,
    nix run, nix profile add, nix-shell -p, nix-env -iA nixpkgs.htop, nix-build, nix-collect-garbage and
    the rest, with the module's own Nix (nothing to download) and Nixup's store. nixpkgs there is the config's own
    (the registry's and <nixpkgs>, NixOS's `nixpkgs.flake.setF...

Read more