diff --git a/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml b/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml index 58cd2b4142a..5037bd6b2df 100644 --- a/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml +++ b/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml @@ -27,3 +27,5 @@ links: url: https://issues.apache.org/jira/browse/SOLR-18516 - name: SOLR-18519 url: https://issues.apache.org/jira/browse/SOLR-18519 + - name: SOLR-18518 + url: https://issues.apache.org/jira/browse/SOLR-18518 diff --git a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java index f60d03c3574..3c5d2a98ad6 100644 --- a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java +++ b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java @@ -247,6 +247,48 @@ public static String normalizeSolrUrl(CommandLine cli) throws Exception { return solrUrl; } + /** + * The picocli counterpart of {@link #normalizeSolrUrl(CommandLine)}: {@code --solr-url}, else the + * connection named by {@code --solr-connection} or {@code --zk-host} (or the matching property + * when the option is absent), else the default URL with the same warning. + * + * @param connectionOptions the parsed connection group, or null if none of its options was given + */ + static String resolveSolrUrl(ConnectionOptions connectionOptions, String credentials) + throws Exception { + String solrUrl = connectionOptions != null ? connectionOptions.solrUrl : null; + if (solrUrl == null) { + String solrConnection = + (connectionOptions != null && connectionOptions.solrConnection != null) + ? connectionOptions.solrConnection + : EnvUtils.getProperty("solr.connection"); + String zkHost = + (connectionOptions != null && connectionOptions.zkHost != null) + ? connectionOptions.zkHost + : EnvUtils.getProperty("zkHost"); + if (solrConnection != null && !solrConnection.isBlank()) { + solrUrl = + solrUrlFromConnection( + CloudSolrClient.CloudSolrClientConnection.parse(solrConnection), credentials); + } else if (zkHost != null && !zkHost.isBlank()) { + var zkSolrConnection = CloudSolrClient.CloudSolrClientConnection.parse(zkHost); + if (!zkSolrConnection.isZookeeper()) { + throw new IOException( + String.format( + Locale.ROOT, "Expected ZooKeeper connection string, but got: '%s'.", zkHost)); + } + solrUrl = solrUrlFromConnection(zkSolrConnection, credentials); + } else { + solrUrl = getDefaultSolrUrl(); + CLIO.err( + "Neither --solr-connection, --zk-host or --solr-url parameters, nor SOLR_CONNECTION, ZK_HOST env var provided, so assuming solr url is " + + solrUrl + + "."); + } + } + return normalizeSolrUrl(solrUrl); + } + /** * Resolves a base Solr URL from a parsed connection. The HTTP form (e.g. {@code -s * http://host:port}) already names a Solr URL, so it is used directly without spinning up a diff --git a/solr/core/src/java/org/apache/solr/cli/CollectionNameOptions.java b/solr/core/src/java/org/apache/solr/cli/CollectionNameOptions.java new file mode 100644 index 00000000000..975ef0708e2 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/CollectionNameOptions.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import picocli.CommandLine; + +/** + * Picocli mixin for the {@code -c} / {@code --name} option naming the collection a command acts on. + */ +class CollectionNameOptions { + + @CommandLine.Option( + names = {"-c", "--name"}, + required = true, + paramLabel = "NAME", + description = "Name of the collection.") + String name; +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotCreateShim.java b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateShim.java new file mode 100644 index 00000000000..22b55a6da09 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateShim.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import org.apache.solr.logging.DeprecationLog; + +/** + * The old top-level {@code snapshot-create} spelling of {@code bin/solr snapshot create}, kept so + * that existing scripts keep working. It is hidden from help and the reference guide. + * + * @deprecated Use {@code bin/solr snapshot create}; this spelling is removed in Solr 11. + */ +@Deprecated(since = "10.2") +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "snapshot-create", + hidden = true, + description = "Deprecated; use 'snapshot create'.") +public class SnapshotCreateShim extends SnapshotCreateTool { + + @Override + public int callTool() throws Exception { + DeprecationLog.log( + "cli.snapshot-create", + "'bin/solr snapshot-create' is deprecated and will be removed in Solr 11; use 'bin/solr snapshot create'."); + return super.callTool(); + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java index 89263c9da2c..5066f75f3bb 100644 --- a/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java @@ -24,8 +24,22 @@ import org.apache.solr.client.solrj.response.CollectionAdminResponse; /** Supports snapshot-create command in the bin/solr script. */ +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "create", + description = "Creates a named snapshot of a collection.", + footerHeading = "%nExamples:%n", + footer = { + " # Create a snapshot", + " bin/solr snapshot create -c mycollection --snapshot-name snap1" + }) public class SnapshotCreateTool extends ToolBase { + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option COLLECTION_NAME_OPTION = Option.builder("c") .longOpt("name") @@ -35,6 +49,11 @@ public class SnapshotCreateTool extends ToolBase { .desc("Name of collection to be snapshot.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option SNAPSHOT_NAME_OPTION = Option.builder() .longOpt("snapshot-name") @@ -48,6 +67,21 @@ public class SnapshotCreateTool extends ToolBase { record SnapshotCreateParams( String solrUrl, String credentials, String collectionName, String snapshotName) {} + // --- picocli fields --- + + @picocli.CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") + private ConnectionOptions connectionOptions; + + @picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions; + + @picocli.CommandLine.Mixin private CollectionNameOptions collection; + + @picocli.CommandLine.Mixin private SnapshotNameOptions snapshot; + + public SnapshotCreateTool() { + this(new DefaultToolRuntime()); + } + public SnapshotCreateTool(ToolRuntime runtime) { super(runtime); } @@ -112,6 +146,13 @@ public void createSnapshot(SolrClient solrClient, String collectionName, String @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + SnapshotCreateParams params = + new SnapshotCreateParams( + CLIUtils.resolveSolrUrl(connectionOptions, credentialsOptions.credentials), + credentialsOptions.credentials, + collection.name, + snapshot.name); + createSnapshot(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteShim.java b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteShim.java new file mode 100644 index 00000000000..9834a17d668 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteShim.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import org.apache.solr.logging.DeprecationLog; + +/** + * The old top-level {@code snapshot-delete} spelling of {@code bin/solr snapshot delete}, kept so + * that existing scripts keep working. It is hidden from help and the reference guide. + * + * @deprecated Use {@code bin/solr snapshot delete}; this spelling is removed in Solr 11. + */ +@Deprecated(since = "10.2") +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "snapshot-delete", + hidden = true, + description = "Deprecated; use 'snapshot delete'.") +public class SnapshotDeleteShim extends SnapshotDeleteTool { + + @Override + public int callTool() throws Exception { + DeprecationLog.log( + "cli.snapshot-delete", + "'bin/solr snapshot-delete' is deprecated and will be removed in Solr 11; use 'bin/solr snapshot delete'."); + return super.callTool(); + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java index 7ff35e5e95a..399796c9835 100644 --- a/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java @@ -24,8 +24,22 @@ import org.apache.solr.client.solrj.response.CollectionAdminResponse; /** Supports snapshot-delete command in the bin/solr script. */ +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "delete", + description = "Deletes a named snapshot of a collection.", + footerHeading = "%nExamples:%n", + footer = { + " # Delete a snapshot", + " bin/solr snapshot delete -c mycollection --snapshot-name snap1" + }) public class SnapshotDeleteTool extends ToolBase { + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option COLLECTION_NAME_OPTION = Option.builder("c") .longOpt("name") @@ -35,6 +49,11 @@ public class SnapshotDeleteTool extends ToolBase { .desc("Name of collection to manage.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option SNAPSHOT_NAME_OPTION = Option.builder() .longOpt("snapshot-name") @@ -48,6 +67,21 @@ public class SnapshotDeleteTool extends ToolBase { record SnapshotDeleteParams( String solrUrl, String credentials, String collectionName, String snapshotName) {} + // --- picocli fields --- + + @picocli.CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") + private ConnectionOptions connectionOptions; + + @picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions; + + @picocli.CommandLine.Mixin private CollectionNameOptions collection; + + @picocli.CommandLine.Mixin private SnapshotNameOptions snapshot; + + public SnapshotDeleteTool() { + this(new DefaultToolRuntime()); + } + public SnapshotDeleteTool(ToolRuntime runtime) { super(runtime); } @@ -112,6 +146,13 @@ public void deleteSnapshot(SolrClient solrClient, String collectionName, String @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + SnapshotDeleteParams params = + new SnapshotDeleteParams( + CLIUtils.resolveSolrUrl(connectionOptions, credentialsOptions.credentials), + credentialsOptions.credentials, + collection.name, + snapshot.name); + deleteSnapshot(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeShim.java b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeShim.java new file mode 100644 index 00000000000..8426c875484 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeShim.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import org.apache.solr.logging.DeprecationLog; + +/** + * The old top-level {@code snapshot-describe} spelling of {@code bin/solr snapshot describe}, kept + * so that existing scripts keep working. It is hidden from help and the reference guide. + * + * @deprecated Use {@code bin/solr snapshot describe}; this spelling is removed in Solr 11. + */ +@Deprecated(since = "10.2") +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "snapshot-describe", + hidden = true, + description = "Deprecated; use 'snapshot describe'.") +public class SnapshotDescribeShim extends SnapshotDescribeTool { + + @Override + public int callTool() throws Exception { + DeprecationLog.log( + "cli.snapshot-describe", + "'bin/solr snapshot-describe' is deprecated and will be removed in Solr 11; use 'bin/solr snapshot describe'."); + return super.callTool(); + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java index d945c23d57f..9793903ccfc 100644 --- a/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java @@ -34,8 +34,22 @@ import org.apache.solr.core.snapshots.SolrSnapshotManager; /** Supports snapshot-describe command in the bin/solr script. */ +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "describe", + description = "Describes a named snapshot of a collection.", + footerHeading = "%nExamples:%n", + footer = { + " # Describe a snapshot", + " bin/solr snapshot describe -c mycollection --snapshot-name snap1" + }) public class SnapshotDescribeTool extends ToolBase { + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option COLLECTION_NAME_OPTION = Option.builder("c") .longOpt("name") @@ -45,6 +59,11 @@ public class SnapshotDescribeTool extends ToolBase { .desc("Name of collection to be snapshot.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option SNAPSHOT_NAME_OPTION = Option.builder() .longOpt("snapshot-name") @@ -58,6 +77,21 @@ public class SnapshotDescribeTool extends ToolBase { record SnapshotDescribeParams( String solrUrl, String credentials, String collectionName, String snapshotName) {} + // --- picocli fields --- + + @picocli.CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") + private ConnectionOptions connectionOptions; + + @picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions; + + @picocli.CommandLine.Mixin private CollectionNameOptions collection; + + @picocli.CommandLine.Mixin private SnapshotNameOptions snapshot; + + public SnapshotDescribeTool() { + this(new DefaultToolRuntime()); + } + public SnapshotDescribeTool(ToolRuntime runtime) { super(runtime); } @@ -151,6 +185,13 @@ private Collection listCollectionSnapshots( @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + SnapshotDescribeParams params = + new SnapshotDescribeParams( + CLIUtils.resolveSolrUrl(connectionOptions, credentialsOptions.credentials), + credentialsOptions.credentials, + collection.name, + snapshot.name); + describeSnapshot(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotExportShim.java b/solr/core/src/java/org/apache/solr/cli/SnapshotExportShim.java new file mode 100644 index 00000000000..4cb77cf05f2 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotExportShim.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import org.apache.solr.logging.DeprecationLog; + +/** + * The old top-level {@code snapshot-export} spelling of {@code bin/solr snapshot export}, kept so + * that existing scripts keep working. It is hidden from help and the reference guide. + * + * @deprecated Use {@code bin/solr snapshot export}; this spelling is removed in Solr 11. + */ +@Deprecated(since = "10.2") +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "snapshot-export", + hidden = true, + description = "Deprecated; use 'snapshot export'.") +public class SnapshotExportShim extends SnapshotExportTool { + + @Override + public int callTool() throws Exception { + DeprecationLog.log( + "cli.snapshot-export", + "'bin/solr snapshot-export' is deprecated and will be removed in Solr 11; use 'bin/solr snapshot export'."); + return super.callTool(); + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java index 8544122e261..06b8017c1ed 100644 --- a/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java @@ -28,11 +28,25 @@ import org.apache.solr.common.params.CollectionAdminParams; /** Supports snapshot-export command in the bin/solr script. */ +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "export", + description = "Backs up a collection's current state to a local directory.", + footerHeading = "%nExamples:%n", + footer = { + " # Export a collection's current state as a backup", + " bin/solr snapshot export -c mycollection --dest-dir /tmp/backups --backup-repo-name local" + }) public class SnapshotExportTool extends ToolBase { private static final DateTimeFormatter BACKUP_NAME_TIMESTAMP = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'", Locale.ROOT).withZone(ZoneOffset.UTC); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option COLLECTION_NAME_OPTION = Option.builder("c") .longOpt("name") @@ -46,6 +60,11 @@ public class SnapshotExportTool extends ToolBase { * Accepted only so that passing it can be rejected with an explanation. Selecting a named * snapshot to export required the non-incremental backup format, which no longer exists. */ + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option SNAPSHOT_NAME_OPTION = Option.builder() .longOpt("snapshot-name") @@ -54,6 +73,11 @@ public class SnapshotExportTool extends ToolBase { .desc("No longer supported; passing it fails with an error.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option DEST_DIR_OPTION = Option.builder() .longOpt("dest-dir") @@ -63,6 +87,11 @@ public class SnapshotExportTool extends ToolBase { .desc("Path of a temporary directory on local filesystem during snapshot export command.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option BACKUP_REPO_NAME_OPTION = Option.builder() .longOpt("backup-repo-name") @@ -72,6 +101,11 @@ public class SnapshotExportTool extends ToolBase { "Specifies name of the backup repository to be used during snapshot export preparation.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option ASYNC_ID_OPTION = Option.builder() .longOpt("async-id") @@ -90,6 +124,48 @@ record SnapshotExportParams( String backupRepo, String asyncReqId) {} + // --- picocli fields --- + + @picocli.CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") + private ConnectionOptions connectionOptions; + + @picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions; + + @picocli.CommandLine.Mixin private CollectionNameOptions collection; + + // Accepted only so that passing it can be rejected with an explanation; see callTool(). + @picocli.CommandLine.Option( + names = "--snapshot-name", + paramLabel = "NAME", + description = "No longer supported; passing it fails with an error.") + private String snapshotNameOpt; + + @picocli.CommandLine.Option( + names = "--dest-dir", + required = true, + paramLabel = "DIR", + description = + "Path of a temporary directory on local filesystem during snapshot export command.") + private String destDirOpt; + + @picocli.CommandLine.Option( + names = "--backup-repo-name", + paramLabel = "NAME", + description = + "Specifies name of the backup repository to be used during snapshot export preparation.") + private String backupRepoNameOpt; + + @picocli.CommandLine.Option( + names = "--async-id", + paramLabel = "ID", + description = + "Specifies the async request identifier to be used during snapshot export preparation.") + private String asyncIdOpt; + + public SnapshotExportTool() { + this(new DefaultToolRuntime()); + } + public SnapshotExportTool(ToolRuntime runtime) { super(runtime); } @@ -178,6 +254,21 @@ public void exportSnapshot( @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + if (snapshotNameOpt != null) { + throw new IllegalArgumentException( + "--snapshot-name is no longer supported. Exporting a named snapshot required the " + + "non-incremental backup format, which was removed in Solr 11; this command now " + + "always backs up the collection's current state. Re-run without --snapshot-name."); + } + SnapshotExportParams params = + new SnapshotExportParams( + CLIUtils.resolveSolrUrl(connectionOptions, credentialsOptions.credentials), + credentialsOptions.credentials, + collection.name, + destDirOpt, + backupRepoNameOpt, + asyncIdOpt); + exportSnapshot(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotListShim.java b/solr/core/src/java/org/apache/solr/cli/SnapshotListShim.java new file mode 100644 index 00000000000..4085ead8ff0 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotListShim.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import org.apache.solr.logging.DeprecationLog; + +/** + * The old top-level {@code snapshot-list} spelling of {@code bin/solr snapshot list}, kept so that + * existing scripts keep working. It is hidden from help and the reference guide. + * + * @deprecated Use {@code bin/solr snapshot list}; this spelling is removed in Solr 11. + */ +@Deprecated(since = "10.2") +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "snapshot-list", + hidden = true, + description = "Deprecated; use 'snapshot list'.") +public class SnapshotListShim extends SnapshotListTool { + + @Override + public int callTool() throws Exception { + DeprecationLog.log( + "cli.snapshot-list", + "'bin/solr snapshot-list' is deprecated and will be removed in Solr 11; use 'bin/solr snapshot list'."); + return super.callTool(); + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java index a4d7ea3b56a..4649215b53e 100644 --- a/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java @@ -26,8 +26,19 @@ import org.apache.solr.core.snapshots.SolrSnapshotManager; /** Supports snapshot-list command in the bin/solr script. */ +@SuppressWarnings("UnnecessarilyFullyQualified") +@picocli.CommandLine.Command( + name = "list", + description = "Lists the snapshots for a collection.", + footerHeading = "%nExamples:%n", + footer = {" # List a collection's snapshots", " bin/solr snapshot list -c mycollection"}) public class SnapshotListTool extends ToolBase { + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option COLLECTION_NAME_OPTION = Option.builder("c") .longOpt("name") @@ -40,6 +51,19 @@ public class SnapshotListTool extends ToolBase { /** Parameters for the snapshot-list command, independent of the command line parser. */ record SnapshotListParams(String solrUrl, String credentials, String collectionName) {} + // --- picocli fields --- + + @picocli.CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") + private ConnectionOptions connectionOptions; + + @picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions; + + @picocli.CommandLine.Mixin private CollectionNameOptions collection; + + public SnapshotListTool() { + this(new DefaultToolRuntime()); + } + public SnapshotListTool(ToolRuntime runtime) { super(runtime); } @@ -99,6 +123,12 @@ public void listSnapshots(SolrClient solrClient, String collectionName) { @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + SnapshotListParams params = + new SnapshotListParams( + CLIUtils.resolveSolrUrl(connectionOptions, credentialsOptions.credentials), + credentialsOptions.credentials, + collection.name); + listSnapshots(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotNameOptions.java b/solr/core/src/java/org/apache/solr/cli/SnapshotNameOptions.java new file mode 100644 index 00000000000..c4a95de9976 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotNameOptions.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import picocli.CommandLine; + +/** Picocli mixin for the {@code --snapshot-name} option shared by the snapshot sub-commands. */ +class SnapshotNameOptions { + + @CommandLine.Option( + names = "--snapshot-name", + required = true, + paramLabel = "NAME", + description = "Name of the snapshot.") + String name; +} diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotTool.java b/solr/core/src/java/org/apache/solr/cli/SnapshotTool.java new file mode 100644 index 00000000000..6c7aba2e33a --- /dev/null +++ b/solr/core/src/java/org/apache/solr/cli/SnapshotTool.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import java.util.concurrent.Callable; +import picocli.CommandLine; + +/** + * Sub commands for working with collection snapshots, only here to provide a common parent for the + * subcommands and print tool help. + */ +@CommandLine.Command( + name = "snapshot", + description = "Sub commands for working with collection snapshots.", + footer = "\nPass --help or -h after any COMMAND to see command-specific usage information.", + subcommands = { + SnapshotCreateTool.class, + SnapshotDeleteTool.class, + SnapshotDescribeTool.class, + SnapshotExportTool.class, + SnapshotListTool.class + }) +public class SnapshotTool implements Callable { + @CommandLine.Mixin HelpMixin helpMixin; + @CommandLine.Spec CommandLine.Model.CommandSpec spec; + + @Override + public Integer call() { + spec.commandLine().usage(CLIO.getOutStream()); + return 0; + } +} diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java index 4f2c27d6681..f1936cf8d68 100755 --- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java +++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java @@ -89,7 +89,13 @@ HealthcheckTool.class, PostTool.class, PostLogsTool.class, - StreamTool.class + StreamTool.class, + SnapshotTool.class, + SnapshotCreateShim.class, + SnapshotDeleteShim.class, + SnapshotDescribeShim.class, + SnapshotExportShim.class, + SnapshotListShim.class }) public class SolrCLI implements CLIO, java.util.concurrent.Callable { diff --git a/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolPicocliTest.java b/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolPicocliTest.java new file mode 100644 index 00000000000..8be7c47e459 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolPicocliTest.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +/** + * Runs the {@link SnapshotExportToolTest} tests that go through {@code runTool} using the {@code + * bin/solr snapshot export} sub-command; the tests that call the commons-cli parser directly are + * inherited and run unchanged. + */ +public class SnapshotExportToolPicocliTest extends SnapshotExportToolTest { + + @Override + protected int runTool( + String[] args, CLITestHelper.TestingRuntime runtime, Class clazz) + throws Exception { + return SnapshotToolsPicocliTest.runAsGroup(args, runtime); + } +} diff --git a/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolTest.java b/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolTest.java index 81c46f302dd..a3c45246a10 100644 --- a/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolTest.java +++ b/solr/core/src/test/org/apache/solr/cli/SnapshotExportToolTest.java @@ -37,6 +37,13 @@ @LuceneTestCase.SuppressCodecs({"SimpleText"}) public class SnapshotExportToolTest extends SolrCloudTestCase { + /** Runs the tool. Overridden by the picocli variant of this test. */ + protected int runTool( + String[] args, CLITestHelper.TestingRuntime runtime, Class clazz) + throws Exception { + return CLITestHelper.runTool(args, runtime, clazz); + } + private static final String COLLECTION = "snapshot_export_coll"; @BeforeClass @@ -124,6 +131,29 @@ public void testSnapshotNameNoLongerRequired() throws Exception { Arrays.stream(cli.getOptions()).anyMatch(o -> "snapshot-name".equals(o.getLongOpt()))); } + /** Whichever parser runs, the option is refused with an error exit and nothing is written. */ + @Test + public void testSnapshotNameIsRefusedWithAnErrorExit() throws Exception { + Path destDir = newDestDir(); + int exitCode = + runTool( + new String[] { + "snapshot-export", + "-c", + COLLECTION, + "--dest-dir", + destDir.toString(), + "--solr-url", + solrUrl(), + "--snapshot-name", + "snap1" + }, + new CLITestHelper.TestingRuntime(false), + SnapshotExportTool.class); + assertEquals(1, exitCode); + assertEquals(List.of(), backupDirs(destDir)); + } + @Test public void testBackupNameIsDerivedFromCollectionAndTime() { assertEquals( @@ -137,7 +167,7 @@ public void testExportWritesBackupUnderTheDerivedName() throws Exception { Path destDir = newDestDir(); CLITestHelper.TestingRuntime runtime = new CLITestHelper.TestingRuntime(true); int exitCode = - CLITestHelper.runTool( + runTool( new String[] { "snapshot-export", "-c", diff --git a/solr/core/src/test/org/apache/solr/cli/SnapshotToolsPicocliTest.java b/solr/core/src/test/org/apache/solr/cli/SnapshotToolsPicocliTest.java new file mode 100644 index 00000000000..649c5185cf9 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/cli/SnapshotToolsPicocliTest.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import java.util.ArrayList; +import java.util.List; +import org.apache.solr.logging.DeprecationLog; +import org.apache.solr.util.LogListener; +import org.junit.Test; +import picocli.CommandLine; + +/** + * Runs {@link SnapshotToolsTest} through picocli, using the {@code bin/solr snapshot } + * group, and checks that the old {@code snapshot-*} spellings still work as hidden, deprecated + * shims. + */ +public class SnapshotToolsPicocliTest extends SnapshotToolsTest { + + /** + * Builds the real root command, giving each tool the test's runtime so its output is captured. + */ + private static CommandLine root(CLITestHelper.TestingRuntime runtime) { + CommandLine.IFactory factory = + new CommandLine.IFactory() { + @Override + public K create(Class cls) throws Exception { + if (ToolBase.class.isAssignableFrom(cls)) { + try { + return cls.getDeclaredConstructor(ToolRuntime.class).newInstance(runtime); + } catch (NoSuchMethodException e) { + // a shim: it has only the default constructor + } + } + return CommandLine.defaultFactory().create(cls); + } + }; + return new CommandLine(new SolrCLI(), factory); + } + + /** Runs a commons-cli style {@code snapshot- ...} command line as {@code snapshot ...}. */ + static int runAsGroup(String[] args, CLITestHelper.TestingRuntime runtime) { + List grouped = + new ArrayList<>(List.of("snapshot", args[0].substring("snapshot-".length()))); + grouped.addAll(List.of(args).subList(1, args.length)); + return root(runtime).execute(grouped.toArray(new String[0])); + } + + @Override + protected int runTool( + String[] args, CLITestHelper.TestingRuntime runtime, Class clazz) + throws Exception { + return runAsGroup(args, runtime); + } + + @Test + public void testConnectionFallsBackToTheSolrConnectionProperty() throws Exception { + // SOLR_CONNECTION reaches the JVM as the solr.connection property + run(SnapshotCreateTool.class, "snapshot-create", "--snapshot-name", "snapViaConnection"); + + System.setProperty("solr.connection", cluster.getZkClient().getZkServerAddress()); + CLITestHelper.TestingRuntime runtime = new CLITestHelper.TestingRuntime(true); + assertEquals( + 0, + runTool(new String[] {"snapshot-list", "-c", COLLECTION}, runtime, SnapshotListTool.class)); + assertTrue(runtime.getOutput(), runtime.getOutput().contains("snapViaConnection")); + run(SnapshotDeleteTool.class, "snapshot-delete", "--snapshot-name", "snapViaConnection"); + } + + @Test + public void testOldSpellingsStillWork() throws Exception { + CommandLine root = root(new CLITestHelper.TestingRuntime(true)); + String url = cluster.getJettySolrRunner(0).getBaseUrl().toString(); + + // the notice is logged once per JVM, and this is the only test that runs the old spellings + try (LogListener deprecation = + LogListener.warn(DeprecationLog.LOG_PREFIX + "cli.snapshot-create")) { + assertEquals( + 0, + root.execute( + "snapshot-create", + "-c", + COLLECTION, + "--snapshot-name", + "oldSpelling", + "--solr-url", + url)); + String notice = deprecation.pollMessage(); + assertNotNull("a deprecation notice is logged", notice); + assertTrue(notice, notice.contains("bin/solr snapshot create")); + } + assertTrue(run(SnapshotListTool.class, "snapshot-list").contains("oldSpelling")); + assertEquals( + 0, + root.execute( + "snapshot-delete", + "-c", + COLLECTION, + "--snapshot-name", + "oldSpelling", + "--solr-url", + url)); + assertFalse(run(SnapshotListTool.class, "snapshot-list").contains("oldSpelling")); + } + + /** Goes with the shims, which are removed in Solr 11. */ + @Deprecated + @Test + public void testOldSpellingsAreHiddenAndDeprecated() { + CommandLine root = root(new CLITestHelper.TestingRuntime(true)); + for (String sub : List.of("create", "delete", "describe", "export", "list")) { + CommandLine shim = root.getSubcommands().get("snapshot-" + sub); + assertNotNull("snapshot-" + sub, shim); + assertTrue("snapshot-" + sub, shim.getCommandSpec().usageMessage().hidden()); + Deprecated deprecated = shim.getCommand().getClass().getAnnotation(Deprecated.class); + assertNotNull("snapshot-" + sub, deprecated); + assertEquals("10.2", deprecated.since()); + } + assertFalse(root.getUsageMessage().contains("snapshot-create")); + assertTrue(root.getUsageMessage().contains("snapshot")); + } + + @Test + public void testGroupListsItsSubCommands() { + String usage = + root(new CLITestHelper.TestingRuntime(true)) + .getSubcommands() + .get("snapshot") + .getUsageMessage(); + for (String sub : List.of("create", "delete", "describe", "export", "list")) { + assertTrue(sub + " in " + usage, usage.contains(sub)); + } + } +} diff --git a/solr/core/src/test/org/apache/solr/cli/SnapshotToolsTest.java b/solr/core/src/test/org/apache/solr/cli/SnapshotToolsTest.java new file mode 100644 index 00000000000..5389dfe1573 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/cli/SnapshotToolsTest.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.cli; + +import java.util.ArrayList; +import java.util.List; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.cloud.SolrCloudTestCase; +import org.apache.solr.common.SolrInputDocument; +import org.junit.BeforeClass; +import org.junit.Test; + +/** The snapshot-create, -list, -describe and -delete commands through the command line. */ +public class SnapshotToolsTest extends SolrCloudTestCase { + static final String COLLECTION = "snapshotToolsColl"; + + /** Runs the tool. Overridden by the picocli variant of this test. */ + protected int runTool( + String[] args, CLITestHelper.TestingRuntime runtime, Class clazz) + throws Exception { + return CLITestHelper.runTool(args, runtime, clazz); + } + + @BeforeClass + public static void setupCluster() throws Exception { + configureCluster(1).addConfig("conf", configset("cloud-minimal")).configure(); + CollectionAdminRequest.createCollection(COLLECTION, "conf", 1, 1) + .process(cluster.getSolrClient()); + cluster.waitForActiveCollection(COLLECTION, 1, 1); + cluster.getSolrClient().add(COLLECTION, new SolrInputDocument("id", "1")); + cluster.getSolrClient().commit(COLLECTION); + } + + String run(Class tool, String name, String... extra) throws Exception { + List args = + new ArrayList<>( + List.of( + name, + "-c", + COLLECTION, + "--solr-url", + cluster.getJettySolrRunner(0).getBaseUrl().toString())); + args.addAll(List.of(extra)); + CLITestHelper.TestingRuntime runtime = new CLITestHelper.TestingRuntime(true); + assertEquals(0, runTool(args.toArray(new String[0]), runtime, tool)); + return runtime.getOutput(); + } + + @Test + public void testSnapshotLifecycle() throws Exception { + run(SnapshotCreateTool.class, "snapshot-create", "--snapshot-name", "snap1"); + + assertTrue(run(SnapshotListTool.class, "snapshot-list").contains("snap1")); + + String described = + run(SnapshotDescribeTool.class, "snapshot-describe", "--snapshot-name", "snap1"); + assertTrue(described, described.contains("Name: snap1")); + + run(SnapshotDeleteTool.class, "snapshot-delete", "--snapshot-name", "snap1"); + + assertFalse(run(SnapshotListTool.class, "snapshot-list").contains("snap1")); + } + + // snapshot-list reports a failed request in its output and still exits 0, so check the output. + @Test + public void testConnectionFallsBackToTheZkHostProperty() throws Exception { + run(SnapshotCreateTool.class, "snapshot-create", "--snapshot-name", "snapViaProperty"); + + System.setProperty("zkHost", cluster.getZkClient().getZkServerAddress()); + CLITestHelper.TestingRuntime runtime = new CLITestHelper.TestingRuntime(true); + assertEquals( + 0, + runTool(new String[] {"snapshot-list", "-c", COLLECTION}, runtime, SnapshotListTool.class)); + assertTrue(runtime.getOutput(), runtime.getOutput().contains("snapViaProperty")); + run(SnapshotDeleteTool.class, "snapshot-delete", "--snapshot-name", "snapViaProperty"); + } +} diff --git a/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc b/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc index 074440d2a99..034346e499d 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc @@ -31,6 +31,12 @@ *** xref:cli/solr-healthcheck.adoc[healthcheck] *** xref:cli/solr-post.adoc[post] *** xref:cli/solr-postlogs.adoc[postlogs] +*** xref:cli/solr-snapshot.adoc[snapshot] +**** xref:cli/solr-snapshot-create.adoc[create] +**** xref:cli/solr-snapshot-delete.adoc[delete] +**** xref:cli/solr-snapshot-describe.adoc[describe] +**** xref:cli/solr-snapshot-export.adoc[export] +**** xref:cli/solr-snapshot-list.adoc[list] *** xref:cli/solr-start.adoc[start] *** xref:cli/solr-status.adoc[status] *** xref:cli/solr-stop.adoc[stop] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc index e7e950ea5e1..4dbe2b5dea4 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc @@ -70,6 +70,12 @@ Any command not listed here is unavailable when the picocli implementation is en |xref:cli/solr-healthcheck.adoc[bin/solr healthcheck] |xref:cli/solr-post.adoc[bin/solr post] |xref:cli/solr-postlogs.adoc[bin/solr postlogs] +|xref:cli/solr-snapshot-create.adoc[bin/solr snapshot create] +|xref:cli/solr-snapshot-delete.adoc[bin/solr snapshot delete] +|xref:cli/solr-snapshot-describe.adoc[bin/solr snapshot describe] +|xref:cli/solr-snapshot-export.adoc[bin/solr snapshot export] +|xref:cli/solr-snapshot-list.adoc[bin/solr snapshot list] +|xref:cli/solr-snapshot.adoc[bin/solr snapshot] |xref:cli/solr-start.adoc[bin/solr start] |xref:cli/solr-status.adoc[bin/solr status] |xref:cli/solr-stop.adoc[bin/solr stop] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-create.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-create.adoc new file mode 100644 index 00000000000..e4b1b14c008 --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-create.adoc @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot create +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot create [-hv] -c=NAME --snapshot-name=NAME [-u=] + [-s= | --solr-url= | -z=] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Creates a named snapshot of a collection. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-c*, *--name*=_NAME_:: + *(required)* Name of the collection. + +*-h*, *--help*:: + Print this help message and exit. + +*-s*, *--solr-connection*=__:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--snapshot-name*=_NAME_:: + *(required)* Name of the snapshot. + +*--solr-url*=__:: + Base Solr URL, which can be used to determine the zk-host if that's not known. + +*-u*, *--credentials*=__:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*-z*, *--zk-host*=__:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # Create a snapshot + bin/solr snapshot create -c mycollection --snapshot-name snap1 + +// end::picocli-generated-man-section-footer[] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-delete.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-delete.adoc new file mode 100644 index 00000000000..eadf9e84b7c --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-delete.adoc @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot delete +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot delete [-hv] -c=NAME --snapshot-name=NAME [-u=] + [-s= | --solr-url= | -z=] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Deletes a named snapshot of a collection. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-c*, *--name*=_NAME_:: + *(required)* Name of the collection. + +*-h*, *--help*:: + Print this help message and exit. + +*-s*, *--solr-connection*=__:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--snapshot-name*=_NAME_:: + *(required)* Name of the snapshot. + +*--solr-url*=__:: + Base Solr URL, which can be used to determine the zk-host if that's not known. + +*-u*, *--credentials*=__:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*-z*, *--zk-host*=__:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # Delete a snapshot + bin/solr snapshot delete -c mycollection --snapshot-name snap1 + +// end::picocli-generated-man-section-footer[] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-describe.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-describe.adoc new file mode 100644 index 00000000000..11e6a1a31ce --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-describe.adoc @@ -0,0 +1,85 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot describe +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot describe [-hv] -c=NAME --snapshot-name=NAME [-u=] + [-s= | --solr-url= | + -z=] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Describes a named snapshot of a collection. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-c*, *--name*=_NAME_:: + *(required)* Name of the collection. + +*-h*, *--help*:: + Print this help message and exit. + +*-s*, *--solr-connection*=__:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--snapshot-name*=_NAME_:: + *(required)* Name of the snapshot. + +*--solr-url*=__:: + Base Solr URL, which can be used to determine the zk-host if that's not known. + +*-u*, *--credentials*=__:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*-z*, *--zk-host*=__:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # Describe a snapshot + bin/solr snapshot describe -c mycollection --snapshot-name snap1 + +// end::picocli-generated-man-section-footer[] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-export.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-export.adoc new file mode 100644 index 00000000000..606617e3f3c --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-export.adoc @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot export +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot export [-hv] [--async-id=ID] [--backup-repo-name=NAME] -c=NAME + --dest-dir=DIR [--snapshot-name=NAME] [-u=] + [-s= | --solr-url= | -z=] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Backs up a collection's current state to a local directory. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*--async-id*=_ID_:: + Specifies the async request identifier to be used during snapshot export preparation. + +*--backup-repo-name*=_NAME_:: + Specifies name of the backup repository to be used during snapshot export preparation. + +*-c*, *--name*=_NAME_:: + *(required)* Name of the collection. + +*--dest-dir*=_DIR_:: + *(required)* Path of a temporary directory on local filesystem during snapshot export command. + +*-h*, *--help*:: + Print this help message and exit. + +*-s*, *--solr-connection*=__:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--snapshot-name*=_NAME_:: + No longer supported; passing it fails with an error. + +*--solr-url*=__:: + Base Solr URL, which can be used to determine the zk-host if that's not known. + +*-u*, *--credentials*=__:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*-z*, *--zk-host*=__:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # Export a collection's current state as a backup + bin/solr snapshot export -c mycollection --dest-dir /tmp/backups --backup-repo-name local + +// end::picocli-generated-man-section-footer[] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-list.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-list.adoc new file mode 100644 index 00000000000..d0139e4520a --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot-list.adoc @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot list +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot list [-hv] -c=NAME [-u=] [-s= | + --solr-url= | -z=] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Lists the snapshots for a collection. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-c*, *--name*=_NAME_:: + *(required)* Name of the collection. + +*-h*, *--help*:: + Print this help message and exit. + +*-s*, *--solr-connection*=__:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--solr-url*=__:: + Base Solr URL, which can be used to determine the zk-host if that's not known. + +*-u*, *--credentials*=__:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*-z*, *--zk-host*=__:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # List a collection's snapshots + bin/solr snapshot list -c mycollection + +// end::picocli-generated-man-section-footer[] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot.adoc new file mode 100644 index 00000000000..f0b674d0678 --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-snapshot.adoc @@ -0,0 +1,74 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr snapshot +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr snapshot [-h] [COMMAND] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Sub commands for working with collection snapshots. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-h*, *--help*:: + Print this help message and exit. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-commands[] +== Commands + +xref:cli/solr-snapshot-create.adoc[*create*]:: + Creates a named snapshot of a collection. + +xref:cli/solr-snapshot-delete.adoc[*delete*]:: + Deletes a named snapshot of a collection. + +xref:cli/solr-snapshot-describe.adoc[*describe*]:: + Describes a named snapshot of a collection. + +xref:cli/solr-snapshot-export.adoc[*export*]:: + Backs up a collection's current state to a local directory. + +xref:cli/solr-snapshot-list.adoc[*list*]:: + Lists the snapshots for a collection. + +// end::picocli-generated-man-section-commands[] diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index 3a5a236542a..d8450340a57 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -34,6 +34,22 @@ This compatibility safeguard can be disabled via the environment variable `SOLR_ Solr 10.0 requires at least Java 21, while SolrJ 10.0 requires at least Java 17. +== Solr 10.2 + +=== Snapshot commands are now `bin/solr snapshot` sub-commands + +The `snapshot-create`, `snapshot-delete`, `snapshot-describe`, `snapshot-export` and `snapshot-list` commands of the experimental picocli command line interface are replaced by the sub-commands of `bin/solr snapshot`: + +[source,bash] +---- +bin/solr snapshot create -c mycollection --snapshot-name snap1 +bin/solr snapshot list -c mycollection +---- + +The old spellings still work and are hidden from the help and from this guide. +They are deprecated in Solr 10.2 and are removed in Solr 11.0. +The default command line interface is not changed. + == Solr 10.1 === Misc