Uploaded image for project: 'Dev - Nexus Repo'
  1. Dev - Nexus Repo
  2. NEXUS-12942

possible to create a repository without a valid blobstore reference

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 3.3.0
    • Fix Version/s: None
    • Component/s: Repository
    • Story Points:
      2
    • Notability:
      3

      Description

      1. In browser window A, create a blobstore named test
      2. In browser window B start creating a repository that refers to blobstore test, but do not save it yet
      3. In browser window A, delete the blobstore test
      4. In browser window B, save the repository. It will save successfully, referring to non-existent blobstore test
      5. Try to delete the repository, you cannot - the delete will fail because the blobstore does not exist

      The same thing can be done with a groovy script when calling RepositoryManager.create(config) API directly. There is not validation on save of a repo that a blobstore exists by that name.

      Example groovy script that can also put Nexus in this state:

      import org.sonatype.nexus.blobstore.api.BlobStoreManager
      import org.sonatype.nexus.repository.storage.WritePolicy
      import org.sonatype.nexus.repository.maven.VersionPolicy
      import org.sonatype.nexus.repository.maven.LayoutPolicy
      import org.sonatype.nexus.repository.Repository
      import groovy.json.*
      import org.sonatype.nexus.repository.config.Configuration
      
      jsonSlurper = new JsonSlurper()
      
      //JSON used to recreate new config each time we need because Map used as Configuration constructor argument points to the same objects
      defaultRepoconfig = JsonOutput.toJson([
      //repositoryName: repoName,
      //recipeName: "maven2-hosted",
      online: true,
      attributes: [
      maven : [
      versionPolicy: VersionPolicy.RELEASE,
      layoutPolicy : LayoutPolicy.STRICT
      ],
      proxy : [
      //remoteUrl: url,
      contentMaxAge: 1440.0,
      metadataMaxAge: 1440.0
      ],
      httpclient: [
      blocked: false,
      autoBlock: true,
      //authentication: authentication,
      connection: [
      useTrustStore: false
      ]
      ],
      storage: [
      //blobStoreName: "Blob-Repo-Internal-Maven",
      strictContentTypeValidation: true,
      writePolicy: WritePolicy.ALLOW_ONCE
      ],
      negativeCache: [
      enabled: true,
      timeToLive: 1440.0
      ]
      ]
      ])
      
      def reposConfig = [
      [
      repositoryName : "Repo-Internal-Maven-InHouseCompos-Common-Releases"
      ]
      ];
      
      def response = [];
      
      reposConfig.each {
      Repository repo = null;
      try{
      
      if(repository.getRepositoryManager().get(it.repositoryName)) {
      repository.getRepositoryManager().delete(it.repositoryName)
      }
      
      def config = getConfiguration(it)
      repo = repository.getRepositoryManager().create(config)
      response << config
      
      }catch(Exception e){
      log.error("ALM Error : " + e.message)
      }
      }
      
      
      return response;
      
      
      Configuration getConfiguration(repo) {
      config = jsonSlurper.parseText(defaultRepoconfig)
      def test = (config as ConfigObject).merge( repo as ConfigObject )
      def configuration = new Configuration(test)
      
      if(repo.repositoryName =~ "(?i).*?Maven.*") {
      configuration.recipeName = "maven2-"
      } else if(repo.repositoryName =~ "(?i).*?NuGet.*") {
      configuration.recipeName = "nuget-"
      } else if(repo.repositoryName =~ "(?i).*?Npm.*") {
      configuration.recipeName = "npm-"
      }
      if(repo.repositoryName =~ "(?i)Repo-External.*") {
      configuration.recipeName += "proxy"
      } else if(repo.repositoryName =~ "(?i)Repo-Internal.*") {
      configuration.recipeName += "hosted"
      } else if(repo.repositoryName =~ "(?i)Group-.*") {
      configuration.recipeName += "group"
      }
      
      if(repo.repositoryName =~ "(?i).*?Maven.*?Snapshot.*") {
      configuration.attributes.maven.versionPolicy = VersionPolicy.SNAPSHOT
      }
      
      def blobStoreName = repo.repositoryName.replaceAll(/([^-]+-[^-]+-[^-]+).*/) {fullMatch, extract ->
      return "Blob-$extract"
      }
      
      
      
      configuration.attributes.storage.blobStoreName = blobStoreName
      
      return configuration;
      
      }

       

      Workaround

      In order to fix the invalid state:

      • create blobstore name that matches the name referenced by the repo
      • restart Nexus ( without restart, repo delete still fails with)
      2017-04-19 11:02:31,145-0300 ERROR [qtp253133175-171] admin org.sonatype.nexus.extdirect.internal.ExtDirectServlet - Failed to invoke action method: coreui_Repository.remove, java-method: org.sonatype.nexus.coreui.RepositoryComponent.remove
      org.sonatype.nexus.common.stateguard.InvalidStateException: Invalid state: FAILED; allowed: [STARTED]
      at org.sonatype.nexus.common.stateguard.StateGuard._ensure(StateGuard.java:115) [na:na]
      at org.sonatype.nexus.common.stateguard.StateGuard.access$1(StateGuard.java:108) [na:na]
      at org.sonatype.nexus.common.stateguard.StateGuard$TransitionImpl.run(StateGuard.java:185) [na:na]
      at org.sonatype.nexus.common.stateguard.TransitionsInterceptor.invoke(TransitionsInterceptor.java:56) [na:na]
      at org.sonatype.nexus.repository.manager.internal.RepositoryManagerImpl.delete(RepositoryManagerImpl.java:370) [na:na]
      at org.sonatype.nexus.common.stateguard.MethodInvocationAction.run(MethodInvocationAction.java:39) [na:na]

       

      • delete repository
      • delete blobstore

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned
              Reporter:
              plynch Peter Lynch
              Last Updated By:
              Rich Seddon
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Date of First Response:

                  tigCommentSecurity.panel-title