This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new c3ed5a80f61 SOLR-17875: Rationalize bootstrap_conf, bootstrap_confdir, 
and -Dcollection.configName in start up scripts (#3512)
c3ed5a80f61 is described below

commit c3ed5a80f61265acb8d66931c8df611ec8a797ee
Author: Eric Pugh <[email protected]>
AuthorDate: Fri Aug 29 09:25:08 2025 -0400

    SOLR-17875: Rationalize bootstrap_conf, bootstrap_confdir, and 
-Dcollection.configName in start up scripts (#3512)
    
    * Add BATS test for bootstrap_confdir and collection.configName system 
properties
    
    Co-authored-by: epugh <[email protected]>
    
    * Complete BATS test for bootstrap_confdir system property with 
techproducts configset
    
    * Remove unused code, left over from old demo in early Solrcloud days 
related to "collection1"
    
    * Drop bootstrap_conf parameter
    
    * rename bootstrap_confdir to modern name
    
    * Add support for relative solr bootstrap path
    
    * assume Solr.install.dir is set.
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] 
<[email protected]>
    Co-authored-by: epugh <[email protected]>
---
 solr/bin/solr                                      |  5 --
 solr/bin/solr.cmd                                  |  4 --
 .../cloud/api/collections/CreateCollectionCmd.java |  5 +-
 .../org/apache/solr/core/ConfigSetService.java     | 82 +++++++++++-----------
 solr/packaging/test/test_start_solr.bats           | 11 +++
 .../solr/common/cloud/TestZkConfigSetService.java  | 25 -------
 .../DeprecatedSystemPropertyMappings.properties    |  2 +
 7 files changed, 54 insertions(+), 80 deletions(-)

diff --git a/solr/bin/solr b/solr/bin/solr
index d9b0bacb4da..2f1cb2933bf 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -1091,11 +1091,6 @@ if [ "${SOLR_MODE:-}" == 'solrcloud' ]; then
     CLOUD_MODE_OPTS+=("-DcreateZkChroot=$ZK_CREATE_CHROOT")
   fi
 
-  # and if collection1 needs to be bootstrapped
-  if [ -e "$SOLR_HOME/collection1/core.properties" ]; then
-    CLOUD_MODE_OPTS+=('-Dbootstrap_confdir=./solr/collection1/conf' 
'-Dcollection.configName=myconf' '-DnumShards=1')
-  fi
-
   if [ "${SOLR_SOLRXML_REQUIRED:-false}" == "true" ]; then
     CLOUD_MODE_OPTS+=("-Dsolr.solrxml.required=true")
   fi
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index d8c3f5d4561..744a39a45b8 100755
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -936,10 +936,6 @@ IF "%SOLR_MODE%"=="solrcloud" (
     set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -Dsolr.solrxml.required=true"
   )
 
-  IF EXIST "%SOLR_HOME%\collection1\core.properties" set 
"CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -Dbootstrap_confdir=./solr/collection1/conf 
-Dcollection.configName=myconf -DnumShards=1"
-) ELSE (
-  REM change Cloud mode to User Managed mode with flag
-  set "CLOUD_MODE_OPTS="
   IF NOT EXIST "%SOLR_HOME%\solr.xml" (
     IF "%SOLR_SOLRXML_REQUIRED%"=="true" (
       set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% must contain solr.xml!"
diff --git 
a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
 
b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
index e216a7726bc..d6cff4013ed 100644
--- 
a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
+++ 
b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
@@ -683,7 +683,7 @@ public class CreateCollectionCmd implements 
CollApiCmds.CollectionApiCommand {
                   stateManager, collection, collectionPath, collectionProps, 
configSetService);
             }
 
-          } else if (System.getProperty("bootstrap_confdir") != null) {
+          } else if (System.getProperty("solr.configset.bootstrap.confdir") != 
null) {
             String defaultConfigName =
                 System.getProperty(
                     ZkController.COLLECTION_PARAM_PREFIX + 
ZkController.CONFIGNAME_PROP,
@@ -706,9 +706,6 @@ public class CreateCollectionCmd implements 
CollApiCmds.CollectionApiCommand {
             if (!collectionProps.containsKey(ZkController.CONFIGNAME_PROP))
               collectionProps.put(ZkController.CONFIGNAME_PROP, 
defaultConfigName);
 
-          } else if (Boolean.getBoolean("bootstrap_conf")) {
-            // the conf name should should be the collection name of this core
-            collectionProps.put(ZkController.CONFIGNAME_PROP, collection);
           } else {
             getConfName(
                 stateManager, collection, collectionPath, collectionProps, 
configSetService);
diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java 
b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
index 0d737c27d61..9cecd032eea 100644
--- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
+++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
@@ -31,8 +31,8 @@ import org.apache.solr.cloud.ZkConfigSetService;
 import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.ConfigNode;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.EnvUtils;
 import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.handler.admin.ConfigSetsHandler;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.IndexSchemaFactory;
@@ -85,22 +85,17 @@ public abstract class ConfigSetService {
   }
 
   private void bootstrapConfigSet(CoreContainer coreContainer) {
-    // bootstrap _default conf, bootstrap_confdir and bootstrap_conf if 
provided via system property
+    // bootstrap _default conf and solr.configset.bootstrap.confdir if 
specified.
     try {
       // _default conf
       bootstrapDefaultConf();
 
-      // bootstrap_confdir
-      String confDir = System.getProperty("bootstrap_confdir");
+      // solr.configset.bootstrap.confdir
+      String confDir = 
EnvUtils.getProperty("solr.configset.bootstrap.confdir");
       if (confDir != null) {
         bootstrapConfDir(confDir);
       }
 
-      // bootstrap_conf
-      boolean boostrapConf = Boolean.getBoolean("bootstrap_conf");
-      if (boostrapConf == true) {
-        bootstrapConf(coreContainer);
-      }
     } catch (IOException e) {
       throw new SolrException(
           SolrException.ErrorCode.SERVER_ERROR, "Config couldn't be uploaded 
", e);
@@ -114,7 +109,7 @@ public abstract class ConfigSetService {
         log.warn(
             "The _default configset could not be uploaded. Please provide 
'solr.configset.default.confdir' parameter that points to a configset {} {}",
             "intended to be the default. Current 
'solr.configset.default.confdir' value:",
-            
System.getProperty(SolrDispatchFilter.SOLR_CONFIGSET_DEFAULT_CONFDIR_ATTRIBUTE));
+            
EnvUtils.getProperty(SolrDispatchFilter.SOLR_CONFIGSET_DEFAULT_CONFDIR_ATTRIBUTE));
       } else {
         this.uploadConfig(ConfigSetsHandler.DEFAULT_CONFIGSET_NAME, 
configDirPath);
       }
@@ -122,15 +117,19 @@ public abstract class ConfigSetService {
   }
 
   private void bootstrapConfDir(String confDir) throws IOException {
-    Path configPath = Path.of(confDir);
+    if (!confDir.endsWith("conf")) {
+      throw new IllegalArgumentException(
+          "solr.configset.bootstrap.confdir must point to 'conf' directory, 
confDir: " + confDir);
+    }
+
+    Path configPath = resolvePathWithSolrInstallDir(confDir);
+
     if (!Files.isDirectory(configPath)) {
       throw new IllegalArgumentException(
-          "bootstrap_confdir must be a directory of configuration files, 
configPath: "
+          "solr.configset.bootstrap.confdir must be a directory of 
configuration files, configPath: "
               + configPath);
     }
-    String confName =
-        System.getProperty(
-            ZkController.COLLECTION_PARAM_PREFIX + 
ZkController.CONFIGNAME_PROP, "configuration1");
+    String confName = EnvUtils.getProperty("solr.collection.config.name", 
"configuration1");
     this.uploadConfig(confName, configPath);
   }
 
@@ -139,23 +138,23 @@ public abstract class ConfigSetService {
    * sysprop "solr.configset.default.confdir". If not found, tries to find the 
_default dir relative
    * to the sysprop "solr.install.dir". Returns null if not found anywhere.
    *
-   * @lucene.internal
    * @see SolrDispatchFilter#SOLR_CONFIGSET_DEFAULT_CONFDIR_ATTRIBUTE
    */
   public static Path getDefaultConfigDirPath() {
     String confDir =
-        
System.getProperty(SolrDispatchFilter.SOLR_CONFIGSET_DEFAULT_CONFDIR_ATTRIBUTE);
+        
EnvUtils.getProperty(SolrDispatchFilter.SOLR_CONFIGSET_DEFAULT_CONFDIR_ATTRIBUTE);
     if (confDir != null) {
-      Path path = Path.of(confDir);
+      Path path = resolvePathWithSolrInstallDir(confDir);
       if (Files.exists(path)) {
         return path;
       }
     }
 
-    String installDir = 
System.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE);
+    String installDir = 
EnvUtils.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE);
     if (installDir != null) {
+      Path installPath = resolvePathWithSolrInstallDir(installDir);
       Path subPath = Path.of("server", "solr", "configsets", "_default", 
"conf");
-      Path path = Path.of(installDir).resolve(subPath);
+      Path path = installPath.resolve(subPath);
       if (Files.exists(path)) {
         return path;
       }
@@ -164,6 +163,27 @@ public abstract class ConfigSetService {
     return null;
   }
 
+  /**
+   * Resolves a path string into a Path object, handling both absolute and 
relative paths. If the
+   * path is relative then it resolves it against Solr installation directory 
by looking up the
+   * solr.install.dir system property.
+   *
+   * @param pathStr The path of the directory to resolve
+   * @return The resolved Path object
+   * @see SolrDispatchFilter#SOLR_INSTALL_DIR_ATTRIBUTE
+   */
+  public static Path resolvePathWithSolrInstallDir(String pathStr) {
+    Path path = Path.of(pathStr);
+
+    // Convert to absolute path if it's relative
+    if (!path.isAbsolute()) {
+      String installDir = 
EnvUtils.getProperty(SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE);
+      path = Path.of(installDir).resolve(path).normalize();
+    }
+
+    return path;
+  }
+
   // Order is important here since "confDir" may be
   // 1> a full path to the parent of a solrconfig.xml or parent of 
/conf/solrconfig.xml
   // 2> one of the canned config sets only, e.g. _default
@@ -198,28 +218,6 @@ public abstract class ConfigSetService {
             Path.of(configSetDir, confDir, "conf", 
"solrconfig.xml").normalize().toAbsolutePath()));
   }
 
-  /** If in SolrCloud mode, upload configSets for each SolrCore in solr.xml. */
-  public static void bootstrapConf(CoreContainer cc) throws IOException {
-    // List<String> allCoreNames = cfg.getAllCoreNames();
-    List<CoreDescriptor> cds = cc.getCoresLocator().discover(cc);
-
-    if (log.isInfoEnabled()) {
-      log.info(
-          "bootstrapping config for {} cores into ZooKeeper using solr.xml 
from {}",
-          cds.size(),
-          cc.getSolrHome());
-    }
-
-    for (CoreDescriptor cd : cds) {
-      String coreName = cd.getName();
-      String confName = cd.getCollectionName();
-      if (StrUtils.isNullOrEmpty(confName)) confName = coreName;
-      Path udir = cd.getInstanceDir().resolve("conf");
-      log.info("Uploading directory {} with name {} for solrCore {}", udir, 
confName, coreName);
-      cc.getConfigSetService().uploadConfig(confName, udir);
-    }
-  }
-
   /**
    * Load the ConfigSet for a core
    *
diff --git a/solr/packaging/test/test_start_solr.bats 
b/solr/packaging/test/test_start_solr.bats
index 2ba80e44e95..767cd9c355d 100644
--- a/solr/packaging/test/test_start_solr.bats
+++ b/solr/packaging/test/test_start_solr.bats
@@ -93,3 +93,14 @@ teardown() {
   solr start --jettyconfig "--module=server"
   solr assert --started http://localhost:${SOLR_PORT} --timeout 5000
 }
+
+@test "bootstrap configset using bootstrap_confdir and collection.configName" {
+  local 
confdir_path="${SOLR_TIP}/server/solr/configsets/sample_techproducts_configs/conf"
+  test -d "${confdir_path}"
+  
+  # This uploads the sample_techproducts_configs/conf directory as 
"techproducts_bootstrapped" configset
+  solr start -Dsolr.configset.bootstrap.confdir="${confdir_path}" 
-Dsolr.collection.config.name=techproducts_bootstrapped
+  
+  solr assert --started http://localhost:${SOLR_PORT} --timeout 5000
+  config_exists "techproducts_bootstrapped"
+}
diff --git 
a/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
 
b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
index 7d083d330a3..9928d543210 100644
--- 
a/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
+++ 
b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
@@ -23,17 +23,14 @@ import java.nio.file.Path;
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 import org.apache.curator.framework.AuthInfo;
 import org.apache.curator.framework.api.ACLProvider;
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.cloud.AbstractZkTestCase;
 import org.apache.solr.cloud.ZkConfigSetService;
 import org.apache.solr.cloud.ZkTestServer;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.core.ConfigSetService;
-import org.apache.solr.core.CoreContainer;
 import org.apache.solr.util.LogLevel;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.ZooDefs;
@@ -228,28 +225,6 @@ public class TestZkConfigSetService extends SolrTestCaseJ4 
{
     }
   }
 
-  @Test
-  public void testBootstrapConf() throws IOException, KeeperException, 
InterruptedException {
-
-    Path solrHome = legacyExampleCollection1SolrHome();
-
-    CoreContainer cc = new CoreContainer(solrHome, new Properties());
-    System.setProperty("zkHost", zkServer.getZkAddress());
-
-    SolrZkClient zkClient =
-        new SolrZkClient.Builder()
-            .withUrl(zkServer.getZkHost())
-            .withTimeout(AbstractZkTestCase.TIMEOUT, TimeUnit.MILLISECONDS)
-            .build();
-    zkClient.makePath("/solr", false, true);
-    cc.setCoreConfigService(new ZkConfigSetService(zkClient));
-    assertFalse(cc.getConfigSetService().checkConfigExists("collection1"));
-    ConfigSetService.bootstrapConf(cc);
-    assertTrue(cc.getConfigSetService().checkConfigExists("collection1"));
-
-    zkClient.close();
-  }
-
   static SolrZkClient buildZkClient(
       String zkAddress,
       final ACLProvider aclProvider,
diff --git 
a/solr/solrj/src/resources/DeprecatedSystemPropertyMappings.properties 
b/solr/solrj/src/resources/DeprecatedSystemPropertyMappings.properties
index 9c2aa1e519f..0d3c5a47b48 100644
--- a/solr/solrj/src/resources/DeprecatedSystemPropertyMappings.properties
+++ b/solr/solrj/src/resources/DeprecatedSystemPropertyMappings.properties
@@ -28,3 +28,5 @@ basicauth=solr.security.auth.basicauth.credentials
 cloud.solr.client.max.stale.retries=solr.solrj.cloud.max.stale.retries
 configset.upload.enabled=solr.configset.upload.enabled
 solr.hidden.sys.props=solr.responses.hidden.sys.props
+bootstrap_confdir=solr.configset.bootstrap.confdir
+collection.config.name=solr.collection.config.name

Reply via email to