From cf4a7d217a14a1e9ca6a1138a78b199187a4baf5 Mon Sep 17 00:00:00 2001 From: akhil Date: Mon, 7 Mar 2022 23:22:32 +0530 Subject: [PATCH 1/3] Check build size before adding to builds array in response --- src/Helpers/Builds.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Helpers/Builds.php b/src/Helpers/Builds.php index fb2ce2b..97cdae0 100644 --- a/src/Helpers/Builds.php +++ b/src/Helpers/Builds.php @@ -205,7 +205,10 @@ } if ($build->isValid($this->postData['params'])) { - array_push($this->builds, $build); + // Check that build zip file is not empty + if($build->getSize() > 0) { + array_push($this->builds, $build); + } if (!empty($this->postData['params']) && strcmp($this->postData['params']['source_incremental'], $build->getIncremental()) == 0) { $this->currentBuild = $build; $this->logger->info($build->getIncremental().' is the current build'); -- GitLab From fb20bf16e08e3f6119ae5af5a03cc582823a49a1 Mon Sep 17 00:00:00 2001 From: akhil Date: Wed, 9 Mar 2022 13:08:42 +0530 Subject: [PATCH 2/3] Added incremental rollout feature for builds --- README.md | 24 +++++++++++++++++++++ src/CmOta.php | 39 +++++++++++++++++----------------- src/Helpers/Build.php | 48 +++++++++++++++++++++++++++++++++++++++++- src/Helpers/Builds.php | 9 +++----- 4 files changed, 94 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index beabd27..542c44d 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,30 @@ The fields `device` and `channel` are mandatory and `incremental` is an optional - The contents should be read as: Upgrades from major version 9 to major version 9 and to major version 10 are allowed. Upgrades from major version 10 to major version 10 and to major version 11 are allowed. - Current version is always available as an upgrade (if a more recent build is found), even if file is not available (for backwards compatibility too). +## How to set incremental rollout percentage in build config file + +- You can specify incremental rollout rules by adding values in `config.json` file. You can add the file only if you want percentage incremental rollout for a build. +- The format of file name will be : `.zip.config.json` + +```shell +$ cd builds/full/test/guacamoleb/ +$ tree +. +├── e.x.xx-xxyyzz-guacamoleb.zip # the full ROM zip file +└── e.x.xx-xxyyzz-guacamoleb.zip.config.json # the ROM build.config.json file +``` + +- E.g. : Suppose builds for "guacamoleb" devices are stored at "/mnt/rom/builds/full/test/guacamoleb". The file "/mnt/rom/builds/full/test/guacamoleb/e.x.xx-xxyyzz-guacamoleb.zip.config.json" should then have contents like: +```json + { + "rollout": { + "percentage": 20 + } + } +``` +- The `percentage` value must be between 0 to 100. Do not add `%` sign after the value. +- The `config.json` file is not mandatory. In case it does not exist, a build will consider a 100% rollout percentage. + ### ONLY for LineageOS 15.x and newer If you are willing to use this project on top of your LineageOS 15.x ( or newer ) ROM builds, you may have noticed that the file named `build.prop` have been removed inside your ZIP file, and has been instead integrated within your `system.new.dat` file, which is basically an ext4 image ( you can find out more here: https://source.android.com/devices/tech/ota/block ). diff --git a/src/CmOta.php b/src/CmOta.php index 8df8c54..d04591f 100644 --- a/src/CmOta.php +++ b/src/CmOta.php @@ -110,25 +110,26 @@ // LineageOS new API Flight::route('/api/v1/@deviceType/@romType(/@incrementalVersion)', function ( $deviceType, $romType, $incrementalVersion ){ - Flight::builds()->setPostData( - array( - 'params' => array( - 'device' => $deviceType, - 'channels' => array( - $romType, - ), - 'source_incremental' => $incrementalVersion, - ), - ) - ); - - $ret = array( - 'id' => null, - 'response' => Flight::builds()->get(), - 'error' => null - ); - - Flight::json($ret); + Flight::builds()->setPostData( + array( + 'params' => array( + 'device' => $deviceType, + 'channels' => array( + $romType, + ), + 'source_incremental' => $incrementalVersion, + ), + ) + ); + + $ret = array( + 'id' => null, + 'response' => Flight::builds()->get(), + 'error' => null + ); + + Flight::json($ret); + }); } diff --git a/src/Helpers/Build.php b/src/Helpers/Build.php index a2e8e70..f3061a5 100644 --- a/src/Helpers/Build.php +++ b/src/Helpers/Build.php @@ -38,6 +38,7 @@ private $incremental = ''; private $filePath = ''; private $buildProp = ''; + private $confProp = ''; private $uid = null; private $size = ''; private $logger = null; @@ -82,6 +83,7 @@ // - builds/CURRENT_ZIP_FILE.zip/system/build.prop // - builds/CURRENT_ZIP_FILE.zip.prop ( which must exist ) $this->buildProp = explode("\n", @file_get_contents($this->getPropFilePath())); + $this->confProp = $this->getConfProp(); // Try to fetch build.prop values. In some cases, we can provide a fallback, in other a null value will be given $this->timestamp = intval($this->getBuildPropValue('ro.build.date.utc') ?? filemtime($this->filePath)); $this->incremental = $this->getBuildPropValue('ro.build.version.incremental') ?? ''; @@ -510,4 +512,48 @@ { return is_callable($func) && false === stripos(ini_get('disable_functions'), $func); } - } + + /** + * Check if the current build is valid with multiple conditions + * @param type $params The params dictionary inside the current POST request + * @return boolean True if valid, False if not. + */ + public function includeInResults($params) + { + return $this->isValid($params) && $this->checkRollout(); + } + + /** + * Return the correct config file path (depending of version) + * @return string + */ + private function getConfigFilePath() + { + return file_exists($this->filePath . '.config.json') ? $this->filePath . '.config.json' : ''; + } + + /** + * Return the all values from config file path + * @return JSON if valid otherwise null + */ + private function getConfProp(){ + $configFilePath = $this->getConfigFilePath(); + return ($configFilePath) ? json_decode( file_get_contents($configFilePath) , true) : array(); + } + + /** + * Return if rollout successful or not for a build + * @return boolean + */ + public function checkRollout() + { + $rolloutpercentage = isset($this->confProp['rollout']['percentage']) ? $this->confProp['rollout']['percentage'] : 100; + if ($rolloutpercentage >= 0 && $rolloutpercentage < 100) { + $rand_number = rand(0, 100); + if ($rand_number > $rolloutpercentage) { + return false; + } + } + return true; + } + } \ No newline at end of file diff --git a/src/Helpers/Builds.php b/src/Helpers/Builds.php index 97cdae0..4fa8780 100644 --- a/src/Helpers/Builds.php +++ b/src/Helpers/Builds.php @@ -203,12 +203,9 @@ } else { $build = new Build($file, $dir, $this->logger); } - - if ($build->isValid($this->postData['params'])) { - // Check that build zip file is not empty - if($build->getSize() > 0) { - array_push($this->builds, $build); - } + + if ($build->includeInResults($this->postData['params'])) { + array_push($this->builds, $build); if (!empty($this->postData['params']) && strcmp($this->postData['params']['source_incremental'], $build->getIncremental()) == 0) { $this->currentBuild = $build; $this->logger->info($build->getIncremental().' is the current build'); -- GitLab From a036e4dbac4d312fed62043b0ec0c856382a6c4d Mon Sep 17 00:00:00 2001 From: akhil Date: Wed, 9 Mar 2022 21:19:00 +0530 Subject: [PATCH 3/3] Added size check to includeInResults --- src/Helpers/Build.php | 2 +- src/Helpers/Builds.php | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Helpers/Build.php b/src/Helpers/Build.php index f3061a5..fd97512 100644 --- a/src/Helpers/Build.php +++ b/src/Helpers/Build.php @@ -520,7 +520,7 @@ */ public function includeInResults($params) { - return $this->isValid($params) && $this->checkRollout(); + return $this->isValid($params) && $this->checkRollout() && $this->getSize() > 0; } /** diff --git a/src/Helpers/Builds.php b/src/Helpers/Builds.php index 4fa8780..f4cdbe6 100644 --- a/src/Helpers/Builds.php +++ b/src/Helpers/Builds.php @@ -206,10 +206,12 @@ if ($build->includeInResults($this->postData['params'])) { array_push($this->builds, $build); - if (!empty($this->postData['params']) && strcmp($this->postData['params']['source_incremental'], $build->getIncremental()) == 0) { - $this->currentBuild = $build; - $this->logger->info($build->getIncremental().' is the current build'); - } + } + + $sourceIncremental = isset($this->postData['params']['source_incremental']) ? $this->postData['params']['source_incremental'] : NULL; + if ($build->isValid($this->postData['params']) && $sourceIncremental && strcmp($sourceIncremental, $build->getIncremental()) === 0) { + $this->currentBuild = $build; + $this->logger->info($build->getIncremental().' is the current build'); } } } -- GitLab