Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6a67ecb
docs: output markdown for all options
danielfullmer Feb 9, 2021
f499b20
docs: Deploy documentation on gh-pages
hmenke Feb 9, 2021
e61fd11
docs: update gh-pages on push to docs branch
danielfullmer Feb 9, 2021
7b42ce8
docs: simplify F-Droid instructions
danielfullmer Feb 9, 2021
b1f15fe
Rename kernel.useCustom to kernel.enable
danielfullmer Feb 10, 2021
986f8be
docs: enable examples in autogenerated options docs
danielfullmer Feb 10, 2021
73db85c
docs: improve module options documentation
danielfullmer Feb 10, 2021
d222c1c
apps.prebuilt: fix incorrect packageName type
danielfullmer Feb 10, 2021
5d37810
docs: set CNAME for actions-gh-pages
danielfullmer Feb 10, 2021
4cb1274
docs: fix typo in f-droid.md
danielfullmer Feb 10, 2021
77b30ca
Use lowercase "r" in "robotnix" by default
danielfullmer Feb 10, 2021
b97ead8
docs: Use titlecase for page titles
danielfullmer Feb 10, 2021
18c130d
docs: better description for variant option
danielfullmer Feb 10, 2021
3e03182
docs: improve installation instructions
danielfullmer Feb 24, 2021
392c884
docs: add warning about factory reset
danielfullmer Feb 25, 2021
53a9132
Merge branch 'master' into docs
danielfullmer Feb 25, 2021
999dc94
docs: fix hyperlinks
danielfullmer Mar 2, 2021
cedb1b3
docs: output option default and examples properly
danielfullmer Mar 2, 2021
1747bd0
docs: make manual accessible via flake
danielfullmer Mar 10, 2021
476228a
docs: add "declared by" links and reformat
danielfullmer Mar 10, 2021
e10cfcc
Large documentation pass
danielfullmer Apr 15, 2021
4956f28
Merge branch 'master' into docs
danielfullmer Apr 15, 2021
88dfab6
Add warning on example.nix
danielfullmer Apr 15, 2021
ab86af7
docs: add note to automatically-set "fingerprints"
danielfullmer Apr 15, 2021
b40e997
docs: fix generating index.html
danielfullmer Apr 15, 2021
45f484f
docs: add notes about releaseScript / keyStorePath
danielfullmer Apr 15, 2021
28c8826
Warn if using releaseScript without signing.enable
danielfullmer Apr 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Generate documentation

on:
push:
branches: [ docs ]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to change this back to master? Or do you plan to keep documentation on the docs branch from now on? Or maybe just use both master and docs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to switch it back to master after merging.


jobs:
docs:
name: Build documentation
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0
- uses: cachix/install-nix-action@v12
with:
nix_path: nixpkgs=channel:nixos-20.09
- run: nix-build ./docs -A manual -o manual
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./manual/book
cname: docs.robotnix.org
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ changes occur which require user intervention / configuration changes. These
are highlights since the last update, and are not meant to be an exhaustive
listing of changes. See the git commit log for additional details.

# 2021-XX-XX
## Backward incompatible changes
- Renamed `kernel.useCustom` to `kernel.enable`.

# 2021-02-02
## Highlights:
- Updated vanilla flavor to RQ1A.210205.004
Expand Down
1 change: 1 addition & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ let
options.nixpkgs.overlays = mkOption {
default = [];
type = types.listOf types.unspecified;
description = "Nixpkgs overlays to override the default packages used while building robotnix.";
};

config = {
Expand Down
5 changes: 5 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[book]
language = "en"
multilingual = false
src = "src"
title = "Robotnix"
57 changes: 57 additions & 0 deletions docs/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{ pkgs ? import ../pkgs { } }:

with pkgs.lib;
let
eval = import ../default.nix { inherit pkgs; configuration = { }; };

robotnixOptionsDoc = pkgs.nixosOptionsDoc {
inherit (eval) options;
};

optionsMd =
let
options = robotnixOptionsDoc.optionsNix;
in
concatStrings (map
(name:
let
option = options.${name};
body = ''
${option.description}

'' + optionalString (option ? default) ''
Default: `${builtins.toJSON option.default}`

'' + optionalString (option ? example) ''
Example: `${builtins.toJSON option.example}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one gotcha here, namely that builtins.toJSON will not generate valid Nix code for non-empty lists and non-empty attrsets. The situation is probably also problematic for strings with embedded control characters. However, nixosOptionsDoc.optionsJSON has the same problem. Does nixpkgs contain a function for serializing data as valid Nix? At the same time, as long as none of the corner cases named above apply, using builtins.toJSON should be just fine.

Copy link
Contributor

@hmenke hmenke Feb 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found lib.generator.toPretty which comes very close:

nix-repl> v = { a = [ 1 2 3.14159265 { b = ''x\ny''; } ]; c = "z"; d = x: x + 1; }

nix-repl> lib.generators.toPretty {} v                                             
"{ \"a\" = [ 1 2 ~3.141593 { \"b\" = \"x\\ny\"; } ]; \"c\" = \"z\"; \"d\" = <λ>; }"

It's not so nice that keys in the attrset are always quoted, but at least it's valid Nix. Functions of course cannot be reasonably serialized so representing them by <λ> is quite okay. The only real problem here is the serialization of floating point numbers. I don't see why it wouldn't just print the internal representation.


'' + ''
Type: ${option.type}
'';
in
''
- `${name}`

${concatMapStrings (line: " ${line}\n") (splitString "\n" body)}
''
)
(attrNames options));
in
{
manual = pkgs.stdenv.mkDerivation {
name = "manual";
phases = [ "unpackPhase" "buildPhase" "installPhase" ];
src = ./.;
nativeBuildInputs = [ pkgs.mdbook ];
buildPhase = ''
cp ${builtins.toFile "options.md" optionsMd} src/options.md
mdbook build
'';
installPhase = ''
mkdir $out
cp -R book $out/book
cp -R src $out/src
cp book.toml $out/book.toml
'';
};
}
10 changes: 10 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Summary

- [Welcome to Robotnix](welcome.md)
- [Tutorials]()
- [Installation](installation.md)
- [OTA updates](ota.md)
- [F-Droid repositories](f-droid.md)
- [Remote attestation](attestation.md)
- [Reference]()
- [Options](options.md)
File renamed without changes.
9 changes: 3 additions & 6 deletions docs/f-droid.md → docs/src/f-droid.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@ the public key.

We'll take the microG repository as an example. The repository is located at
https://microg.org/fdroid/repo. To obtain the repository index download the
`index.jar` file from the repository root:
`index.xml` file from the repository root:
```console
$ curl -LO https://microg.org/fdroid/repo/index.jar
$ curl -LO https://microg.org/fdroid/repo/index.xml
```
Java Archives are simply ZIP files with a certain structure, so to get the
repository index out of this file, we unzip the contained `index.xml`:
```console
$ unzip index.jar index.xml

```
The content of this XML file contains metadata about the repository, including
the public key:
Expand Down
File renamed without changes.
Empty file added docs/src/options.md
Empty file.
File renamed without changes.
6 changes: 6 additions & 0 deletions docs/src/welcome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# robotnix - Build Android (AOSP) using Nix

Robotnix is a build system for Android (AOSP) images on top of the Nix package
manager. Instead of having to follow complicated instructions to install
several build tools and fetch source code from multiple sources, robotnix
encapsulates all this complexity in a simple Nix expression.
2 changes: 1 addition & 1 deletion flavors/grapheneos/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ in mkIf (config.flavor == "grapheneos") (mkMerge [
# audit devices using the official upstream build
}
(mkIf (elem config.deviceFamily phoneDeviceFamilies) {
kernel.useCustom = mkDefault true;
kernel.enable = mkDefault true;
kernel.src = mkDefault config.source.dirs."kernel/google/${config.kernel.name}".src;
kernel.configName = config.device;
kernel.relpath = "device/google/${config.device}-kernel";
Expand Down
4 changes: 2 additions & 2 deletions flavors/vanilla/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ in mkIf (config.flavor == "vanilla") (mkMerge [

# TODO: Currently, only build kernel for marlin since it needs verity key in build.
# Could also build for other devices, like is done for Android 11
kernel.useCustom = mkDefault config.signing.enable;
kernel.enable = mkDefault config.signing.enable;
})

]))
Expand Down Expand Up @@ -162,7 +162,7 @@ in mkIf (config.flavor == "vanilla") (mkMerge [
kernelMetadata = (lib.importJSON ./kernel-metadata.json).${kernelTag};
kernelHashes = (lib.importJSON ./kernel-hashes.json).${kernelTag};
in {
kernel.useCustom = mkDefault true;
kernel.enable = mkDefault true;
kernel.configName = mkMerge [
(mkIf (elem config.deviceFamily [ "taimen" "muskie" ]) "wahoo")
(mkIf (config.deviceFamily == "crosshatch") "b1c1")
Expand Down
6 changes: 3 additions & 3 deletions modules/apps/auditor.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ in

domain = mkOption {
type = types.str;
default = "attestation.app";
description = "Domain running the AttestationServer (over https) for remote verification";
description = "Domain running the AttestationServer (over HTTPS) for remote verification";
example = "attestation.example.com";
};
};
};

config = mkIf cfg.enable {
assertions = [ {
assertion = builtins.elem config.device supportedDevices;
message = "Device ${config.device} is currently unsupported for use with auditor app.";
message = "Device ${config.device} is currently unsupported for use with Auditor app.";
} ];

apps.prebuilt.Auditor = {
Expand Down
30 changes: 22 additions & 8 deletions modules/apps/fdroid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,55 @@ in
options.apps.fdroid = {
enable = mkEnableOption "F-Droid";

# See apps/src/main/java/org/fdroid/fdroid/data/DBHelper.java in fdroid source
# Note that changes to this setting will only take effect on a freshly
# installed device--or if the FDroid storage is cleared
# See also `apps/src/main/java/org/fdroid/fdroid/data/DBHelper.java` in F-Droid source
additionalRepos = mkOption {
default = {};
description = ''
Additional F-Droid repositories to include in the default build.
Note that changes to this setting will only take effect on a freshly
installed device--or if the F-Droid storage is cleared.
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
enable = mkEnableOption name;
enable = mkOption {
default = false;
type = types.bool;
description = "Whether to enable this repository by default in F-Droid.";
};

name = mkOption {
default = name;
type = types.str;
description = "Display name to use for this repository";
};

url = mkOption {
type = types.str;
description = "URL for F-Droid repository";
};

description = mkOption {
default = "Empty description"; # fdroid parsing of additional_repos.xml requires all items to have text
type = types.str;
default = "Empty description"; # fdroid parsing of additional_repos.xml requires all items to have text
description = "Longer textual description of this repository";
};

version = mkOption { # Not sure what this one is for exactly
default = 1;
version = mkOption {
type = types.int;
default = 0;
description = "Which version of fdroidserver built this repo";
internal = true;
};

pushRequests = mkOption { # Repo metadata can specify apps to be installed/removed
pushRequests = mkOption {
type = types.strMatching "(ignore|prompt|always)";
description = "Allow this repository to specify apps which should be automatically installed/uninstalled";
default = "ignore";
};

pubkey = mkOption { # Wew these are long AF. TODO: Some way to generate these?
type = types.str;
description = "Public key associated with this repository. Can be found in `/index.xml` under the repo URL.";
};
};
}));
Expand Down
32 changes: 22 additions & 10 deletions modules/apps/prebuilt.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,27 @@ in
options = {
apps.prebuilt = mkOption {
default = {};
description = "Prebuilt APKs to include in the robotnix build";

type = let
_config = config;
in types.attrsOf (types.submodule ({ name, config, ... }: {
options = {
name = mkOption {
default = name;
type = types.str; # No spaces (use strMatching?)
description = "Name of application. (No spaces)";
type = types.str; # TODO: Use strMatching to enforce no spaces?
};

apk = mkOption {
type = types.path;
description = "APK file to include in build";
};

signedApk = mkOption {
type = types.path;
internal = true;
description = "Robotnix-signed version of APK file";
};

fingerprint = mkOption {
Expand All @@ -62,18 +67,19 @@ in
};

packageName = mkOption { # Only used with privapp permissions
type = types.str;
description = "example: com.android.test";
description = "APK's Java-style package name (applicationId). This setting only necessary to be set if also using `privappPermissions`.";
type = types.strMatching "[a-zA-Z0-9_.]*";
example = "com.android.test";
};

certificate = mkOption {
default = toLower name;
type = types.str;
description = ''
Certificate name to sign apk with. Defaults to the name of the prebuilt app.
If it is a device-specific certificate, the cert/key will be ''${keyStorePath}/''${device}/''${certificate}.{x509.pem,pk8}
Otherwise, it will be ''${keyStorePath}/''${certificate}.{x509.pem,pk8}
Finally, the special string "PRESIGNED" will just use the apk as-is.
Name of certificate to sign APK with. Defaults to the name of the prebuilt app.
If it is a device-specific certificate, the cert/key should be under `''${keyStorePath}/''${device}/''${certificate}.{x509.pem,pk8}`.
Otherwise, it should be `''${keyStorePath}/''${certificate}.{x509.pem,pk8}`.
Finally, the special string "PRESIGNED" will just use the APK as-is.
'';
};

Expand All @@ -85,12 +91,14 @@ in
privileged = mkOption {
default = false;
type = types.bool;
description = "Whether this APK should be included as a privileged application.";
};

privappPermissions = mkOption {
default = [];
type = types.listOf types.str;
description = ''
Privileged permissions to apply to this application.
See https://developer.android.com/reference/android/Manifest.permission and note permissions which say
"not for use by third-party applications".
'';
Expand All @@ -100,24 +108,28 @@ in
defaultPermissions = mkOption {
default = [];
type = types.listOf types.str;
description = ''
Permissions which are to be enabled by default without user prompting
'';
description = "Permissions to be enabled by default without user prompting.";
example = ''[ "INSTALL_PACKAGES" ]'';
};

partition = mkOption {
description = "Partition on which to place this app";
type = types.strMatching "(vendor|system|product)";
};

allowInPowerSave = mkOption {
default = false;
type = types.bool;
description = ''
Whether to allow this application to operate in \"power save\" mode.
Disables battery optimization for this app.
'';
};

extraConfig = mkOption {
default = "";
type = types.lines;
internal = true;
};
};

Expand Down
2 changes: 1 addition & 1 deletion modules/apps/updater.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ in
{
options = {
apps.updater = {
enable = mkEnableOption "updater";
enable = mkEnableOption "OTA Updater";

url = mkOption {
type = types.str;
Expand Down
Loading