Skip to content
Merged
10 changes: 5 additions & 5 deletions docs/src/modules/ota.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ described in the next section.

## Actually serving OTA updates over the air

> *Note:* These instructions have only been tested with the Vanilla and
> GrapheneOS flavors. This method likely will not with the LineageOS flavor
> because it uses its own updater.
> *Note:* The Vanilla and GrapheneOS flavors use a different updater than the LineageOS flavor,
> therefore they might behave slightly different from one another.
> The instructions below should however work for both.

Essentially this boils down to just serving the `otaDir` build output on the
web, e.g. with nginx. To receive OTA updates on the device, enable the updater
Expand Down Expand Up @@ -79,9 +79,9 @@ updating before the copy/upload is complete.
$ cp --no-dereference ota-dir /var/www/android
$ tree -l /var/www
/var/www
└── android -> /nix/store/dbjcl9lwn6xif9c0fy8d2wwpn9zi4hw4-sunfish-otaDir
└── android -> /nix/store/dbjcl9lwn6xif9c0fy8d2wwpn9zi4hw4-sunfish-otaDir
├── sunfish-ota_update-2021.02.06.16.zip -> /nix/store/wwr49all6x868f0mdl11369ybfwyir0f-sunfish-ota_update-2021.02.06.16.zip
├── sunfish-stable -> /nix/store/c1rp46m9spncanacglqs5mxk6znfs44s-sunfish-stable
├── sunfish-stable -> /nix/store/c1rp46m9spncanacglqs5mxk6znfs44s-sunfish-stable
└── sunfish-target_files-2021.02.06.16.zip -> /nix/store/8ys21rzjqhi2055d7bd4iwa15fv1m446-sunfish-signed_target_files-2021.02.06.16.zip
```
Of course, this doesn't have to be located at `/var/www` and it's totally
Expand Down
6 changes: 5 additions & 1 deletion flavors/lineageos/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ let
elem mapAttrs mapAttrs' nameValuePair filterAttrs
attrNames getAttrs flatten remove
mkIf mkMerge mkDefault mkForce
importJSON toLower hasPrefix;
importJSON toLower hasPrefix removePrefix;

androidVersionToLineageBranch = {
"10" = "lineage-17.1";
Expand Down Expand Up @@ -70,6 +70,7 @@ in mkIf (config.flavor == "lineageos")
androidVersion = let
defaultBranch = deviceMetadata.${config.device}.branch;
in mkIf (deviceMetadata ? ${config.device}) (mkDefault (lib.toInt lineageBranchToAndroidVersion.${defaultBranch}));
flavorVersion = removePrefix "lineage-" androidVersionToLineageBranch.${toString config.androidVersion};

productNamePrefix = "lineage_"; # product names start with "lineage_"

Expand Down Expand Up @@ -145,6 +146,9 @@ in mkIf (config.flavor == "lineageos")
webview.prebuilt.availableByDefault = mkDefault true;
removedProductPackages = [ "webview" ];

apps.updater.flavor = mkDefault "lineageos";
apps.updater.includedInFlavor = mkDefault true;

# Needed by included kernel build for some devices (pioneer at least)
envPackages = [ pkgs.openssl.dev ] ++ optionals (config.androidVersion == 11) [ pkgs.gcc.cc pkgs.glibc.dev ];

Expand Down
43 changes: 30 additions & 13 deletions modules/apps/updater.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ in
apply = x: if lib.hasSuffix "/" x then x else x + "/";
};

flavor = mkOption {
type = types.enum [ "grapheneos" "lineageos" ];
default = "grapheneos";
description = ''
Which updater package to use, and which kind of metadata to generate for it.
'';
};

includedInFlavor = mkOption {
default = false;
type = types.bool;
Expand All @@ -39,26 +47,35 @@ in
config = mkMerge [
(mkIf cfg.enable (mkMerge [
{
# TODO: It's currently on system partition in upstream. Shouldn't it be on product partition?
system.additionalProductPackages = [ "Updater" ];
}

(mkIf (cfg.flavor == "grapheneos") {
resources.${relpath} = {
inherit (cfg) url;
channel_default = config.channel;
};

# TODO: It's currently on system partition in upstream. Shouldn't it be on product partition?
system.additionalProductPackages = [ "Updater" ];
source.dirs = mkIf (!cfg.includedInFlavor) (mkMerge [
{
${relpath}.src = src;
}
(mkIf (!cfg.includedInFlavor && config.androidVersion >= 11) {
# Add selinux policies
source.dirs."robotnix/updater-sepolicy".src = ./updater-sepolicy;
source.dirs."build/make".postPatch = ''
# Originally from https://github.com/RattlesnakeOS/core-config-repo/blob/0d2cb86007c3b4df98d4f99af3dedf1ccf52b6b1/hooks/aosp_build_pre.sh
sed -i '/product-graph dump-products/a #add selinux policies last\n$(eval include robotnix/updater-sepolicy/sepolicy.mk)' "core/config.mk"
'';
})
]);
})

source.dirs = mkIf (!cfg.includedInFlavor) {
${relpath}.src = src;
(mkIf (cfg.flavor == "lineageos") {
resources."packages/apps/Updater" = mkIf (cfg.flavor == "lineageos") {
updater_server_url = "${cfg.url}lineageos-${config.device}.json";
};
}

# Add selinux policies
(mkIf (!cfg.includedInFlavor && config.androidVersion >= 11) {
source.dirs."robotnix/updater-sepolicy".src = ./updater-sepolicy;
source.dirs."build/make".postPatch = ''
# Originally from https://github.com/RattlesnakeOS/core-config-repo/blob/0d2cb86007c3b4df98d4f99af3dedf1ccf52b6b1/hooks/aosp_build_pre.sh
sed -i '/product-graph dump-products/a #add selinux policies last\n$(eval include robotnix/updater-sepolicy/sepolicy.mk)' "core/config.mk"
'';
})
]))

Expand Down
6 changes: 6 additions & 0 deletions modules/base.nix
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ in
description = "Used to select which Android version to use";
};

flavorVersion = mkOption {
type = types.str;
internal = true;
description = "Version used by this flavor of Android";
};

apiLevel = mkOption {
type = types.int;
internal = true;
Expand Down
49 changes: 40 additions & 9 deletions modules/release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{ config, pkgs, lib, ... }:

let
inherit (lib) mkIf mkDefault mkOption types;
inherit (lib) mkIf mkDefault mkOption types optionalString;

otaTools = config.build.otaTools;

Expand Down Expand Up @@ -134,15 +134,46 @@ in
bootImg = pkgs.runCommand "boot.img" {} "${pkgs.unzip}/bin/unzip -p ${targetFiles} IMAGES/boot.img > $out";

# BUILDID_PLACEHOLDER below was originally config.apv.buildID, but we don't want to have to depend on setting a buildID generally.
otaMetadata = pkgs.writeText "${config.device}-${config.channel}" ''
${config.buildNumber} ${toString config.buildDateTime} BUILDID_PLACEHOLDER ${config.channel}
'';
otaMetadata = (rec {
grapheneos = pkgs.writeText "${config.device}-${config.channel}" ''
${config.buildNumber} ${toString config.buildDateTime} BUILDID_PLACEHOLDER ${config.channel}
'';
lineageos = pkgs.writeText "lineageos-${config.device}.json" (
# https://github.com/LineageOS/android_packages_apps_Updater#server-requirements
builtins.toJSON {
response = [
{
"datetime" = config.buildDateTime;
"filename" = ota.name;
"id" = config.buildNumber;
"romtype" = config.envVars.RELEASE_TYPE;
"size" = "ROM_SIZE";
"url" = "${config.apps.updater.url}${ota.name}";
"version" = config.flavorVersion;
}
];
}
);
}).${config.apps.updater.flavor};

writeOtaMetadata = path: {
grapheneos = ''
cat ${otaMetadata} > ${path}/${config.device}-${config.channel}
'';
lineageos = ''
sed -e "s:\"ROM_SIZE\":$(du -b ${ota} | cut -f1):" ${otaMetadata} > ${path}/lineageos-${config.device}.json
'';
}.${config.apps.updater.flavor};

# TODO: target-files aren't necessary to publish--but are useful to include if prevBuildDir is set to otaDir output
otaDir = pkgs.linkFarm "${config.device}-otaDir" (
(map (p: {name=p.name; path=p;}) ([ ota otaMetadata ] ++ (lib.optional config.incremental incrementalOta)))
++ [{ name="${config.device}-target_files-${config.buildNumber}.zip"; path=targetFiles; }]
);
otaDir = pkgs.runCommand "${config.device}-otaDir" {} ''
mkdir -p $out
ln -s "${ota}" "$out/${ota.name}"
ln -s "${targetFiles}" "$out/${config.device}-target_files-${config.buildNumber}.zip"
${lib.optionalString config.incremental ''ln -s ${incrementalOta} "$out/${incrementalOta.name}"''}

${writeOtaMetadata (placeholder "out")}
'';

# TODO: Do this in a temporary directory. It's ugly to make build dir and ./tmp/* dir gets cleared in these scripts too.
releaseScript =
Expand Down Expand Up @@ -173,7 +204,7 @@ in
echo Building factory image
${factoryImgScript { targetFiles=signedTargetFiles.name; img=img.name; out=factoryImg.name; }}
echo Writing updater metadata
cat ${otaMetadata} > ${config.device}-${config.channel}
${writeOtaMetadata "."}
''; }));
};
}