Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-69361

Bundled version of detached plugin is overwriting newer installed version when updating from pre-2.357 Jenkins

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Blocker Blocker
    • core
    • None
    • Jenkins:2.357
      instance-identity:116.vf8f487400980

      Background/Story:

      • We are upgrading from Jenkins 2.308 to Jenkins 2.364.
      • We are also pulling in the latest versions of all plugins we use, and many require the latest instance-identity (116.vf8f487400980) as a direct or transitive dependency.
      • In Jenkins 2.357, instance-identity was converted to a detached plugin & instance-identity:3.1 is the bundled version.
      • When we start up Jenkins, it overwrites instance-identity:116.vf8f487400980 with instance-identity:3.1 (in the plugins folder). This causes other plugins to fail due to the unsatisfied dependency on instance-identity:116.vf8f487400980.

      Diagnosis:

      I was able to track this (seemingly) errant behavior to hudson.PluginManager, lines 759-788:

      // If this was a plugin that was detached some time in the past i.e. not just one of the
      // plugins that was bundled "for fun".
      if (DetachedPluginsUtil.isDetachedPlugin(name)) {
          VersionNumber installedVersion = getPluginVersion(rootDir, name);
          VersionNumber bundledVersion = getPluginVersion(dir, name);
          // If the plugin is already installed, we need to decide whether to replace it with the bundled version.
          if (installedVersion != null && bundledVersion != null) {
              // If the installed version is older than the bundled version, then it MUST be upgraded.
              // If the installed version is newer than the bundled version, then it MUST NOT be upgraded.
              // If the versions are equal we just keep the installed version.
              return installedVersion.isOlderThan(bundledVersion);
          }
      }
      
      // If it's a plugin that was detached since the last running version.
      for (DetachedPluginsUtil.DetachedPlugin detachedPlugin : detachedPlugins) {
          if (detachedPlugin.getShortName().equals(name)) {
              return true;
          }
      } 

      I manually verified that the `isOlderThan` check is working as expected with the two versions of instance-identity mentioned above, and I believe the first block in this snippet is working as intended.

      However, the second second block goes through each detached plugin added since the last running Jenkins version & blithely returns true without checking if the plugin is already installed. This is the definition of the detachedPlugins list:

      final List<DetachedPluginsUtil.DetachedPlugin> detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(lastExecVersion); 

      For me, the lastExecVersion is 2.308, and the plugin became detached in 2.357, so this second block seems like the culprit in causing the newer version of the plugin to be overriden with the bundled (and older) version of instance-identity.

      I tested this by forcing the lastExecVersion to 2.358 (a version after the plugin became detached). On startup the bundled version (3.1) was no longer overwriting the newer version (116.vf8f487400980), and all of my other plugins were able to load.

      How to reproduce:

      • Boot up a fresh install of Jenkins with any version before 2.357.
      • Install the plugin instance-identity:116.vf8f487400980.
      • Upgrade Jenkins to any version greater than 2.357.
      • Check the version of instance-identity. It should be overwritten with instance-identity:3.1.

      Related issues:

      I notice there have been other, slightly different issues related to how detached plugins are laid down over the years, so this seems like it's been hard to get right:

      Proposed fix:

      I believe a fix would be to update the snippet-ed part of PluginManager above to check that any plugin that became detached since the lastExecVersion isn't already installed with a version that is at least as new as the bundled version. That should prevent the older, bundled version from being overlaid on top of a newer installed version.

      Notice that this isn't an issue with instance-identity in particular. This bug should occur for any plugin that becomes detached when updating to a new version of Jenkins with a newer version than the bundled version installed.

            naveenboni Naveen Boni
            tyjad John Smith
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: