Nextcloud Appstore should not load app before upgrading it
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36.9k
- Forks
- 5.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 713
Description
When you update an app via the "Apps"-page, the current version gets instantiated (including everything in the app.php) which means that a lot of the classes and objects of the current version will get loaded. After that the new version will be downloaded and installed. If the new version of the app has a migration that requires one of the classes which have been already loaded from the old codebase, it will now get an old version of the class. This may cause crashes if the new version requires functionalities in the class which were not present in the old version.
This behavior is also very hard to predict for app developers since you can't test the upgrade via the appstore before you release a stable version (upgrade to nightlies would be a great help there). Manual upgrades will not have this issue since it is either the old version or the new version but never both.
Maybe it would be possible to skip the app during the initialization. Or split downloading the new version and running the upgrade in two requests.
Steps to reproduce
- Install an app (e.g. passwords 2018.5.2)
- Check the app store for updates
- Click the update button (in this case to passwords 2018.6.0)
Expected behavior
The app should get updated using the newer codebase only.
Actual behavior
The app gets initialized with the old codebase. If the the two app versions are incompatible, the update will fail and leave Nextcloud in maintenance mode.
Server configuration
Operating system: Ubuntu 16.04
Web server: Nginx
Database: MariaDB
PHP version: 7.1.x
Nextcloud version: 13.0.2
Updated from an older Nextcloud/ownCloud or fresh install: Fresh Install
Where did you install Nextcloud from: Zip from the Nextcloud Website
Signing status:
Signing status
No errors have been found.
List of activated apps:
App list
Enabled:
- activity: 2.6.1
- bruteforcesettings: 1.0.3
- comments: 1.3.0
- dav: 1.4.6
- federatedfilesharing: 1.3.1
- federation: 1.3.0
- files: 1.8.0
- files_sharing: 1.5.0
- files_texteditor: 2.5.1
- files_trashbin: 1.3.0
- files_versions: 1.6.0
- files_videoplayer: 1.2.0
- firstrunwizard: 2.2.1
- gallery: 18.0.0
- logreader: 2.0.0
- lookup_server_connector: 1.1.0
- nextcloud_announcements: 1.2.0
- notifications: 2.1.2
- oauth2: 1.1.0
- password_policy: 1.3.0
- passwords: 2018.6.3
- provisioning_api: 1.3.0
- serverinfo: 1.3.0
- sharebymail: 1.3.0
- survey_client: 1.1.0
- systemtags: 1.3.0
- twofactor_backupcodes: 1.2.3
- updatenotification: 1.3.0
- workflowengine: 1.3.0
Disabled:
- admin_audit
- encryption
- files_external
- files_pdfviewer
- theming
- user_external
- user_ldap
Nextcloud configuration:
Config report
{
"system": {
"instanceid": "***REMOVED SENSITIVE VALUE***",
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": [
"www.nextcloud.local"
],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"overwrite.cli.url": "https:\/\/www.nextcloud.local",
"dbtype": "mysql",
"version": "13.0.2.1",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"mysql.utf8mb4": true,
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"maintenance": false
}
}
Are you using external storage, if yes which one: no
Are you using encryption: no
Are you using an external user-backend, if yes which one: no
Client configuration
Browser: Firefox 60
Operating system: Ubuntu 18.04
Logs
Nextcloud log (data/nextcloud.log)
Nextcloud log
TypeError: Argument 1 passed to OCA\Passwords\Services\Object\AbstractModelService::__construct() must be of the type string or null, object given, called in /var/www/html/apps/passwords/lib/Services/Object/TagService.php on line 40
/var/www/html/apps/passwords/lib/Services/Object/TagService.php - line 40: OCA\Passwords\Services\Object\AbstractModelService->__construct(Object(OCA\Passwords\Hooks\Manager\HookManager), Object(OCA\Passwords\Db\TagMapper), Object(OCA\Passwords\Services\EnvironmentService))
[internal function] OCA\Passwords\Services\Object\TagService->__construct(Object(OCA\Passwords\Hooks\Manager\HookManager), Object(OCA\Passwords\Db\TagMapper), Object(OCA\Passwords\Services\EnvironmentService))
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 80: ReflectionClass->newInstanceArgs(Array)
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 97: OC\AppFramework\Utility\SimpleContainer->buildClass(Object(ReflectionClass))
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 118: OC\AppFramework\Utility\SimpleContainer->resolve('OCA\\Passwords\\S...')
/var/www/html/lib/private/AppFramework/DependencyInjection/DIContainer.php - line 467: OC\AppFramework\Utility\SimpleContainer->query('OCA\\Passwords\\S...')
/var/www/html/lib/private/AppFramework/DependencyInjection/DIContainer.php - line 438: OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback('OCA\\Passwords\\S...')
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 67: OC\AppFramework\DependencyInjection\DIContainer->query('OCA\\Passwords\\S...')
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 97: OC\AppFramework\Utility\SimpleContainer->buildClass(Object(ReflectionClass))
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 118: OC\AppFramework\Utility\SimpleContainer->resolve('OCA\\Passwords\\M...')
/var/www/html/lib/private/AppFramework/DependencyInjection/DIContainer.php - line 467: OC\AppFramework\Utility\SimpleContainer->query('OCA\\Passwords\\M...')
/var/www/html/lib/private/AppFramework/DependencyInjection/DIContainer.php - line 438: OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback('OCA\\Passwords\\M...')
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 67: OC\AppFramework\DependencyInjection\DIContainer->query('OCA\\Passwords\\M...')
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 97: OC\AppFramework\Utility\SimpleContainer->buildClass(Object(ReflectionClass))
/var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php - line 118: OC\AppFramework\Utility\SimpleContainer->resolve('OCA\\Passwords\\M...')
/var/www/html/lib/private/AppFramework/DependencyInjection/DIContainer.php - line 467: OC\AppFramework\Utility\SimpleContainer->query('OCA\\Passwords\\M...')
/var/www/html/lib/private/ServerContainer.php - line 116: OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback('OCA\\Passwords\\M...')
/var/www/html/lib/private/Repair.php - line 106: OC\ServerContainer->query('OCA\\Passwords\\M...')
/var/www/html/lib/private/legacy/app.php - line 1107: OC\Repair->addStep('OCA\\Passwords\\M...')
/var/www/html/lib/private/legacy/app.php - line 1050: OC_App executeRepairSteps('passwords', Array)
/var/www/html/lib/private/Installer.php - line 201: OC_App updateApp('passwords')
/var/www/html/settings/ajax/updateapp.php - line 45: OC\Installer->updateAppstoreApp('passwords')
/var/www/html/lib/private/Route/Route.php - line 155: require_once('/home/xubiumco/...')
[internal function] OC\Route\Route->OC\Route\{closure}(*** sensitive parameters replaced ***)
/var/www/html/lib/private/Route/Router.php - line 297: call_user_func(Object(Closure), Array)
/var/www/html/lib/base.php - line 999: OC\Route\Router->match('/settings/ajax/...')
/var/www/html/index.php - line 37: OC handleRequest()
{main}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with lib/private/Installer.php around updateAppstoreApp and follow the request from settings/ajax/updateapp.php through the app update and repair steps shown in the trace. Determine how the old app code is initialized before the new version is installed; done means App Store upgrades run using only the newer codebase and do not leave Nextcloud in maintenance mode.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100