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