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

possible to create a repository without a valid blobstore reference

Details

    • 2
    • 3
    • 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

              plynch Peter Lynch
              plynch Peter Lynch
              Michael Oliverio Michael Oliverio
              Votes:
              1 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                tigCommentSecurity.panel-title