Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect if a shipped app is updated and can be updated #8929

Closed
MorrisJobke opened this issue Mar 21, 2018 · 22 comments
Closed

Detect if a shipped app is updated and can be updated #8929

MorrisJobke opened this issue Mar 21, 2018 · 22 comments

Comments

@MorrisJobke
Copy link
Member

See nextcloud/docker#288

Having two app folders configure:

  • /apps with all the shipped apps and the writable flag set to false
  • /apps2 with the writable flag set to true to install apps via the app store

Once we publish an update of a shipped app via the app store the app is put into apps2 and does not replace the original code and thus is not properly updated.

@nickvergessen @rullzer Ideas how to fix? I would try to detect this before the update is triggered by the user or the occ upgrade script.

@nickvergessen
Copy link
Member

I thought our code was clever enough to always load apps from the app dir where they are the newest version?!

@MorrisJobke
Copy link
Member Author

I thought our code was clever enough to always load apps from the app dir where they are the newest version?!

Doesn't seem to be like that and I also haven't seen any code lately while digging through the app management code. 😕

@nickvergessen
Copy link
Member

Found it, the following should take care of it.
Maybe we lost the track to it somewhere:

*/
public static function findAppInDirectories(string $appId) {
$sanitizedAppId = self::cleanAppId($appId);
if($sanitizedAppId !== $appId) {
return false;
}
static $app_dir = [];
if (isset($app_dir[$appId])) {
return $app_dir[$appId];
}
$possibleApps = [];
foreach (OC::$APPSROOTS as $dir) {
if (file_exists($dir['path'] . '/' . $appId)) {
$possibleApps[] = $dir;
}
}
if (empty($possibleApps)) {
return false;
} elseif (count($possibleApps) === 1) {
$dir = array_shift($possibleApps);
$app_dir[$appId] = $dir;
return $dir;
} else {
$versionToLoad = [];
foreach ($possibleApps as $possibleApp) {
$version = self::getAppVersionByPath($possibleApp['path']);
if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
$versionToLoad = array(
'dir' => $possibleApp,
'version' => $version,
);
}
}
$app_dir[$appId] = $versionToLoad['dir'];
return $versionToLoad['dir'];
//TODO - write test
}
}

@j-ed
Copy link
Contributor

j-ed commented Mar 22, 2018

It seems that this issue ticket covers my recently reported update problem (#8938)

@nickvergessen
Copy link
Member

Ah, I think the issue might be psr autoloading paths are not changed.
When the new version is downloaded, it is stored in the new path, and "used". But the class map is still on the old path. So when the path changes, we need to re-register autoloading and overwrite static $app_dir in the code I linked.

@MorrisJobke
Copy link
Member Author

Ah, I think the issue might be psr autoloading paths are not changed.
When the new version is downloaded, it is stored in the new path, and "used". But the class map is still on the old path. So when the path changes, we need to re-register autoloading and overwrite static $app_dir in the code I linked.

Ah ... true that was there as well 🙈

@tilosp
Copy link
Member

tilosp commented Apr 4, 2018

@julijane
Copy link

julijane commented Apr 6, 2018

I would like to mention as pointed out in my pull request, when the configuration below is used it actually works (at least for me in my tests).

It also makes quite some sense to have it like this, because it appears logical to the user that the first path is checked first, and of course the updated app is to be found there then. I think the "writable" flag actually is more confusing and making this unnecessary complicated. I suggest to get rid of that flag and just check the directories in the order stated and always write into the first one. Problem solved with a configuration which is intuitive and makes sense from a logical point of view.

<?php
$CONFIG = array (
  "apps_paths" => array (
      0 => array (
              "path"     => OC::$SERVERROOT."/custom_apps",
              "url"      => "/custom_apps",
              "writable" => true,
      ),
      1 => array (
              "path"     => OC::$SERVERROOT."/apps",
              "url"      => "/apps",
              "writable" => false,
      ),
  ),
);

@rullzer
Copy link
Member

rullzer commented Apr 7, 2018

@julijane ah that makes sense yes.

@nickvergessen looking at your code then we only load the newest version right? So then the paths should actually be right. Or am I missing something?

@tilosp
Copy link
Member

tilosp commented Apr 7, 2018

@rullzer but wouldn't this cause problems the other way around? When for example the pdf viewer get updated by the nextcloud updater. In this Scenario the version in apps would be newer than the version in custom_apps, which would than again cause the same problem.

@rullzer
Copy link
Member

rullzer commented Apr 7, 2018

@tilosp yeah sure. we need to find a proper solution of course. Just taking the latest version.

@julijane
Copy link

julijane commented Apr 7, 2018

@tilosp @rullzer Actually it would be nice if in such a scenario the app is deleted from the custom apps folder. So then you would have always only updated apps in custom apps folder. Maybe make it configurable to do that?

Also I am not sure if always loading the most current app is what is always desired in a multi app path configuration. With the current code it would be possible to "override" a package with a local/older version which would not be affected by updates (but the updatenotification would keep complaining then, of course, but in such a complicated setup you probably would disable it anyway). I have not tested this configuration but I am quite sure that it would work:

<?php
$CONFIG = array (
  "apps_paths" => array (
      0 => array (
              "path"     => OC::$SERVERROOT."/override_apps",
              "url"      => "/override_apps",
              "writable" => false,
      ),
      1 => array (
              "path"     => OC::$SERVERROOT."/custom_apps",
              "url"      => "/custom_apps",
              "writable" => true,
      ),
      2 => array (
              "path"     => OC::$SERVERROOT."/apps",
              "url"      => "/apps",
              "writable" => false,
      ),
  ),
);

Maybe there should be a way to pin a version of a app if desired. Also I am wondering if there should be dependencies between apps. I have seen apps which are a plugin to another app, and then they have to do something like this:

if (\OCP\App::isEnabled('news')
    && class_exists('OCA\News\Plugin\Client\Plugin')) {

(found here: https://github.com/cosenal/mailsharenewsplugin/blob/master/appinfo/app.php)

So stupid checking and no dependency on a specific / minimum version of that other app. The app store is growing and growing and in order to properly support things like apps which are plugins to other apps, there probably should be a package/dependency manager, some sort of apt-equivalent in Nextcloud. Would surely be a lot of work, but it would make a lot of sense.

Just my 2ct :)

@MorrisJobke
Copy link
Member Author

@tilosp @rullzer Actually it would be nice if in such a scenario the app is deleted from the custom apps folder. So then you would have always only updated apps in custom apps folder. Maybe make it configurable to do that?

That is super hard to detect at least from the updater as it doesn't have access to the information in a easy way. I would avoid to have this logic in the updater and would properly handle this in the server code.

Also I am not sure if always loading the most current app is what is always desired in a multi app path configuration. With the current code it would be possible to "override" a package with a local/older version which would not be affected by updates (but the updatenotification would keep complaining then, of course, but in such a complicated setup you probably would disable it anyway). I have not tested this configuration but I am quite sure that it would work:

IMO we should not support something like this. It just asks for trouble :/ We should not overcomplicate things and also not depend on the order of config options too hard.

Maybe there should be a way to pin a version of a app if desired. Also I am wondering if there should be dependencies between apps. I have seen apps which are a plugin to another app, and then they have to do something like this:

Pinning apps works by not clicking "update" in the UI. For major upgrades there is often no way around this. Also we should fix the problem behind the why of "pinning" apps and not add more complexity to allow pinning of app versions.

@MorrisJobke
Copy link
Member Author

So stupid checking and no dependency on a specific / minimum version of that other app. The app store is growing and growing and in order to properly support things like apps which are plugins to other apps, there probably should be a package/dependency manager, some sort of apt-equivalent in Nextcloud. Would surely be a lot of work, but it would make a lot of sense.

No - we don't support this and also don't plan this. Apps should not have inter app dependencies. Reimplementing complex versioning and dependency tools is also nothing we plan to have, because this is far too much to explain users in the web UI why something doesn't work.

@nickvergessen
Copy link
Member

@rullzer

looking at your code then we only load the newest version right? So then the paths should actually be right. Or am I missing something?

Well the thing is the order. All apps are loaded by by our code, then the new version is downloaded and should be used from here on. But the static path map and teh set autloaders are still on the old path (a F5 at the right point would fix it, but this is one script call). We need to invalidate those caches and reregister autoloading at the moment where we unpack the new version and try to run the update code from the new location.

rullzer added a commit that referenced this issue May 3, 2018
Related to #8929

We should get the version of the app. Not of the appfolder. Else there
is no way to properly compare the versions.

Now note that installing in 1 go will still fail. But at least on the
next page load the new version will be properly detected.

Signed-off-by: Roeland Jago Douma <[email protected]>
rullzer added a commit that referenced this issue May 9, 2018
Related to #8929

We should get the version of the app. Not of the appfolder. Else there
is no way to properly compare the versions.

Now note that installing in 1 go will still fail. But at least on the
next page load the new version will be properly detected.

Signed-off-by: Roeland Jago Douma <[email protected]>
@nextcloud-bot nextcloud-bot added the stale Ticket or PR with no recent activity label Jun 20, 2018
@MorrisJobke MorrisJobke removed this from the Nextcloud 14 milestone Jul 25, 2018
@rullzer rullzer modified the milestones: Nextcloud 17.0.4, Nextcloud 17.0.5 Mar 11, 2020
@rullzer rullzer modified the milestones: Nextcloud 17.0.5, Nextcloud 17.0.6 Mar 23, 2020
@rullzer rullzer modified the milestones: Nextcloud 21, Nextcloud 22 Mar 1, 2021
@skjnldsv skjnldsv removed this from the Nextcloud 22 milestone Jun 7, 2021
@skjnldsv skjnldsv added 1. to develop Accepted and waiting to be taken care of and removed 0. Needs triage Pending check for reproducibility or if it fits our roadmap labels Jun 7, 2021
@szaimen
Copy link
Contributor

szaimen commented Jan 9, 2023

Hi, please update to 24.0.8 or better 25.0.2 and report back if it fixes the issue. Thank you!

@szaimen szaimen added needs info 0. Needs triage Pending check for reproducibility or if it fits our roadmap and removed 1. to develop Accepted and waiting to be taken care of labels Jan 9, 2023
@nickvergessen
Copy link
Member

cc @skjnldsv @blizzz Updating shipped apps via the appstore works nowerdays, right?

@blizzz
Copy link
Member

blizzz commented Jan 18, 2023

yes

@blizzz blizzz closed this as completed Jan 18, 2023
@szaimen
Copy link
Contributor

szaimen commented Jan 18, 2023

I think this does not properly work yet: nextcloud/related_resources#170

@szaimen szaimen reopened this Jan 18, 2023
@szaimen szaimen closed this as completed Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests