Skip to content

Commit

Permalink
Polaris Server Admin Tool
Browse files Browse the repository at this point in the history
Implement Bootstrap and Purge commands for the Quarkus server runtime
  • Loading branch information
adutra committed Jan 9, 2025
1 parent 9477208 commit 31aedd4
Show file tree
Hide file tree
Showing 15 changed files with 555 additions and 0 deletions.
2 changes: 2 additions & 0 deletions LICENSE-BINARY-DIST
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ commons-io:commons-io
commons-logging:commons-logging
commons-net:commons-net
dev.failsafe:failsafe
info.picocli:picocli
io.airlift:aircompressor
io.grpc:grpc-alts
io.grpc:grpc-api
Expand Down Expand Up @@ -399,6 +400,7 @@ io.quarkus:quarkus-micrometer-registry-prometheus
io.quarkus:quarkus-mutiny
io.quarkus:quarkus-netty
io.quarkus:quarkus-opentelemetry
io.quarkus:quarkus-picocli
io.quarkus:quarkus-reactive-routes
io.quarkus:quarkus-rest
io.quarkus:quarkus-rest-common
Expand Down
1 change: 1 addition & 0 deletions gradle/projects.main.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ polaris-api-management-service=api/management-service
polaris-service-common=service/common
polaris-quarkus-service=quarkus/service
polaris-quarkus-server=quarkus/server
polaris-quarkus-admin=quarkus/admin
polaris-eclipselink=extension/persistence/eclipselink
polaris-jpa-model=extension/persistence/jpa-model
aggregated-license-report=aggregated-license-report
Expand Down
26 changes: 26 additions & 0 deletions quarkus/admin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Polaris Server Admin Tool

This module contains a maintenance tool for the Polaris server. It is a Quarkus application that can
be used to perform various maintenance tasks targeting Polaris database directly.

Building this module will create a runnable uber-jar that can be executed from the command line.

To also build the Docker image, you can use the following command:

```shell
./gradlew :polaris-quarkus-admin:build -Dquarkus.container-image.build=true
```

## Running the Admin Tool

The admin tool can be run from the command line using the following command:

```shell
java -jar polaris-quarkus-admin-<version>-runner.jar --help
```

Using the Docker image, you can run the admin tool with the following command:

```shell
docker run --rm -it polaris-server-admin-tool:<version> --help
```
86 changes: 86 additions & 0 deletions quarkus/admin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.
*/

import io.quarkus.gradle.tasks.QuarkusBuild

plugins {
alias(libs.plugins.quarkus)
alias(libs.plugins.openapi.generator)
id("polaris-server")
id("polaris-license-report")
}

dependencies {
implementation(project(":polaris-core"))
implementation(project(":polaris-api-management-service"))
implementation(project(":polaris-api-iceberg-service"))
implementation(project(":polaris-service-common"))
implementation(project(":polaris-quarkus-service"))

implementation(platform(libs.quarkus.bom))
implementation("io.quarkus:quarkus-picocli")
implementation("io.quarkus:quarkus-container-image-docker")

implementation("org.jboss.slf4j:slf4j-jboss-logmanager")

// override dnsjava version in dependencies due to https://github.com/dnsjava/dnsjava/issues/329
implementation(platform(libs.dnsjava))

testImplementation(enforcedPlatform(libs.quarkus.bom))
testImplementation("io.quarkus:quarkus-junit5")

testImplementation(platform(libs.junit.bom))
testImplementation(libs.bundles.junit.testing)
}

tasks.withType<ProcessResources>().configureEach {
from("src/main/resources") {
expand("polarisVersion" to version)
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
}

quarkus {
quarkusBuildProperties.put("quarkus.package.type", "uber-jar")
// Pull manifest attributes from the "main" `jar` task to get the
// release-information into the jars generated by Quarkus.
quarkusBuildProperties.putAll(
provider {
tasks
.named("jar", Jar::class.java)
.get()
.manifest
.attributes
.map { e -> "quarkus.package.jar.manifest.attributes.\"${e.key}\"" to e.value.toString() }
.toMap()
}
)
}

publishing {
publications {
named<MavenPublication>("maven") {
val quarkusBuild = tasks.getByName<QuarkusBuild>("quarkusBuild")
artifact(quarkusBuild.runnerJar) {
classifier = "runner"
builtBy(quarkusBuild)
}
}
}
}
42 changes: 42 additions & 0 deletions quarkus/admin/src/main/docker/Dockerfile.jvm
Original file line number Diff line number Diff line change
@@ -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.
#
FROM registry.access.redhat.com/ubi9/openjdk-21:1.20-2.1726695192

LABEL org.opencontainers.image.source=https://github.com/apache/polaris
LABEL org.opencontainers.image.description="Apache Polaris (incubating) Admin Tool"
LABEL org.opencontainers.image.licenses=Apache-2.0

ENV LANGUAGE='en_US:en'

USER root
RUN groupadd --gid 10001 polaris \
&& useradd --uid 10000 --gid polaris polaris \
&& chown -R polaris:polaris /opt/jboss/container \
&& chown -R polaris:polaris /deployments

USER polaris
WORKDIR /deployments
ENV USER=polaris
ENV UID=10000
ENV HOME=/home/polaris
ENV PWD=/deployments

COPY --chown=polaris:polaris build/*-runner.jar /deployments/polaris-server-admin-tool.jar

ENTRYPOINT [ "java", "-jar", "/deployments/polaris-server-admin-tool.jar" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.polaris.service.quarkus.admin;

import jakarta.inject.Inject;
import java.util.concurrent.Callable;
import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
import org.apache.polaris.service.quarkus.persistence.QuarkusPersistenceConfiguration;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Spec;

public abstract class BaseCommand implements Callable<Integer> {

public static final Integer EXIT_CODE_GENERIC_ERROR = 1;
public static final Integer EXIT_CODE_BOOTSTRAP_ERROR = 2;
public static final Integer EXIT_CODE_PURGE_ERROR = 3;

@Inject QuarkusPersistenceConfiguration persistenceConfiguration;

@Inject MetaStoreManagerFactory metaStoreManagerFactory;

@Spec CommandSpec spec;

protected void warnOnInMemory() {
if (persistenceConfiguration.type().equalsIgnoreCase("in-memory")) {
spec.commandLine()
.getErr()
.println(
spec.commandLine()
.getColorScheme()
.errorText(
"""
*********************************************************************************************
** Running the Admin Tool on a Polaris instance with in-memory persistence is meaningless! **
*********************************************************************************************
"""));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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.polaris.service.quarkus.admin;

import java.util.List;
import java.util.Map;
import org.apache.polaris.core.auth.PolarisSecretsManager.PrincipalSecretsResult;
import picocli.CommandLine;

@CommandLine.Command(
name = "bootstrap",
mixinStandardHelpOptions = true,
description = "Bootstraps principal credentials for all realms and prints them to log.")
public class BootstrapCommand extends BaseCommand {

@CommandLine.Option(
names = {"-r", "--realm"},
required = true,
description = "The name of the realm to bootstrap.")
List<String> realms;

@Override
public Integer call() {
warnOnInMemory();

// Execute the bootstrap
Map<String, PrincipalSecretsResult> results = metaStoreManagerFactory.bootstrapRealms(realms);

// Log any errors:
boolean success = true;
for (Map.Entry<String, PrincipalSecretsResult> result : results.entrySet()) {
if (!result.getValue().isSuccess()) {
spec.commandLine()
.getErr()
.printf(
"Bootstrapping `%s` failed: %s%n",
result.getKey(), result.getValue().getReturnStatus().toString());
success = false;
}
}

if (success) {
spec.commandLine().getOut().println("Bootstrap completed successfully.");
return 0;
} else {
spec.commandLine().getErr().println("Bootstrap encountered errors during operation.");
return EXIT_CODE_BOOTSTRAP_ERROR;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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.polaris.service.quarkus.admin;

import io.quarkus.picocli.runtime.annotations.TopCommand;
import java.io.PrintWriter;
import picocli.CommandLine.Command;
import picocli.CommandLine.HelpCommand;

@TopCommand
@Command(
name = "polaris-admin-tool-runner.jar",
mixinStandardHelpOptions = true,
versionProvider = PolarisVersionProvider.class,
description = "Nessie Server Admin Tool",
subcommands = {
HelpCommand.class,
BootstrapCommand.class,
PurgeCommand.class,
})
public class PolarisAdminTool extends BaseCommand {

@Override
public Integer call() {
return info();
}

private int info() {
warnOnInMemory();

PrintWriter out = spec.commandLine().getOut();

out.println("Polaris server information & maintenance tool.");
out.println("Use the 'help' command.");
out.println();
return 0;
}
}
Loading

0 comments on commit 31aedd4

Please sign in to comment.