-
Notifications
You must be signed in to change notification settings - Fork 352
Merge Polaris-Admin to Polaris-Server #3340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
542d619 to
70ad92f
Compare
|
@flyrain : CI fails? 🤔 |
|
@flyrain the CI failure is an interesting one. After some investigation, it seems related to the colored output that we have by default when running server tests:
Quarkus CLI tests seem unable to capture colored output properly. This can be fixed in two ways: by removing the colored output completely for all tests (but that's frustrating) – or by implementing public class RelationalJdbcAdminProfile extends RelationalJdbcProfile {
@Override
public Map<String, String> getConfigOverrides() {...}
@Override
public List<TestResourceEntry> testResources() {...}
// ADD THIS
@Override public String getConfigProfile() { return "cli"; }
}The above will make the test run under the |
| %cli.quarkus.log.category."io.quarkus".level=ERROR | ||
| %cli.quarkus.log.category."io.quarkus.agroal.deployment".level=ERROR | ||
| %cli.quarkus.log.category."org.hibernate.validator".level=ERROR | ||
| %cli.quarkus.log.category."org.apache.polaris.service.config.ServiceProducers".level=ERROR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than silencing the whole class, I'd suggest modifying the maybeBootstrap method as follows:
public void maybeBootstrap(
@Observes Startup event,
MetaStoreManagerFactory factory,
PersistenceConfiguration config,
RealmContextConfiguration realmContextConfiguration) {
if (ConfigUtils.isProfileActive("cli")) {
return; // never bootstrap realms in CLI profile
}
...I'd also suggest moving this method to a separate class, as it is becoming quite big and complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM. Adopted the change.
For moving it to a separate class, I'd suggest to tackle it in a followup PR given the current PR is big already.
dimas-b
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you effort, @flyrain !
I played with a local build of this PR and it seems generally usable 👍
However, I believe the PR still needs some attention in the areas of production checks and CDI in general.
Adding some more specific comments below.
...rc/main/java/org/apache/polaris/persistence/relational/jdbc/RelationalJdbcConfiguration.java
Outdated
Show resolved
Hide resolved
.../org/apache/polaris/persistence/relational/jdbc/RelationalJdbcProductionReadinessChecks.java
Outdated
Show resolved
Hide resolved
.../org/apache/polaris/persistence/relational/jdbc/RelationalJdbcProductionReadinessChecks.java
Outdated
Show resolved
Hide resolved
| public Integer call() { | ||
| PrintWriter out = spec.commandLine().getOut(); | ||
| spec.commandLine().usage(out); | ||
| // When invoked without a subcommand, show usage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is it possible to invoke the Admin CLI without a subcommand now? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both work per my test. I have removed the comment to avoid confusion.
yufei@Yufeis-MacBook-Pro-2 polaris % java -jar runtime/server/build/quarkus-app/quarkus-run.jar -h
Usage: polaris-admin-tool.jar [-hV] [COMMAND]
Polaris administration & maintenance tool
-h, --help Show this help message and exit.
-V, --version Print version information and exit.
Commands:
help Display help information about the specified command.
bootstrap Bootstraps realms and root principal credentials.
purge Purge realms and all associated entities.
yufei@Yufeis-MacBook-Pro-2 polaris % java -jar runtime/server/build/quarkus-app/quarkus-run.jar purge -h
Usage: polaris-admin-tool.jar purge [-hV] -r=<realm> [-r=<realm>]...
Purge realms and all associated entities.
-h, --help Show this help message and exit.
-r, --realm=<realm> The name of a realm to purge.
-V, --version Print version information and exit.
| implementation(project(":polaris-runtime-service")) | ||
|
|
||
| // Dependencies from merged polaris-admin module | ||
| implementation(project(":polaris-core")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? I suppose runtime/server included polaris-core before 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it to compileOnly, otherwise the compilation will fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I did not mean to imply that the dep. was wrong... I was just wondering 🙂
If core is require for complication, we should probably keep it as an implementation dep.
| Instance<ProductionReadinessCheck> checks, | ||
| ReadinessConfiguration config) { | ||
| // Skip production readiness checks in CLI mode - they're only relevant for server deployments | ||
| if ("cli".equals(System.getProperty("quarkus.profile"))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to find a more natural way to perform readiness checks under the CLI env.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'm open for suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's safer to use the following idiom, as more than one profile can be specified with quarkus.profile:
if (ConfigUtils.isProfileActive("cli")) {There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in the new commit. Thanks for the suggestion.
.asf.yaml
Outdated
| - "Quarkus Tests" | ||
| - "Quarkus Integration Tests" | ||
| - "Quarkus Admin Tests" | ||
| - "Quarkus Server Tests" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we simply need to remove Quarkus Admin Tests here, not rename
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed #3370 to unblock this PR.
runtime/server/src/main/java/org/apache/polaris/admintool/config/AdminToolProducers.java
Outdated
Show resolved
Hide resolved
Awesome! Thanks a lot for the suggestion, @adutra! All tests passed now! |
dimas-b
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from my POV this PR is almost ready to merge :) I hope a few new minor comments, below could still be squeezed in.
| quarkus.banner.enabled=false | ||
|
|
||
| # Logging configuration - suppress verbose output for CLI | ||
| quarkus.log.level=WARN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we suppress CONSOLE log instead but keep default levels informative in case a user enabled FILE logging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open for that, but the WARN level logging was carried from the application.properties in the removed admin module,
| quarkus.log.level=WARN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, sorry, I missed that. Current code is fine for now 👍
| # Get the directory | ||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| cd "$SCRIPT_DIR/../admin" | ||
| cd "$SCRIPT_DIR/../server" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for follow-up: with a single binary package, we may want to rename / restructure the binary dist for clarity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, there are a few places needed to be changed, including doc. I will address them in followups.
| Instance<ProductionReadinessCheck> checks, | ||
| ReadinessConfiguration config) { | ||
| // Skip production readiness checks in CLI mode - they're only relevant for server deployments | ||
| if (ConfigUtils.isProfileActive("cli")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably ok in the interest of progress, but in general I hope we could leverage profile-specific config like polaris.production.readiness.checks.enabled=true (or false for CLI). WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's probably a good idea, esp. if we want to group a set of methods under the same configure key, instead of spreed if (ConfigUtils.isProfileActive("cli") in multiple places. We could improve in followups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe using dedicated config properties for this is a small change :) but I'm also ok with addressing this in a follow-up PR.
| MetaStoreManagerFactory factory, | ||
| PersistenceConfiguration config, | ||
| RealmContextConfiguration realmContextConfiguration) { | ||
| if (ConfigUtils.isProfileActive("cli")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: I'd prefer to use explicit config flags (set differently in each profile) vs. checking the name of the profile, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #3340 (comment)
| Instance<ProductionReadinessCheck> checks, | ||
| ReadinessConfiguration config) { | ||
| // Skip production readiness checks in CLI mode - they're only relevant for server deployments | ||
| if (ConfigUtils.isProfileActive("cli")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe using dedicated config properties for this is a small change :) but I'm also ok with addressing this in a follow-up PR.
# Conflicts: # runtime/admin/src/main/docker/Dockerfile.jvm
adutra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good! I only have a few minor comments.
| # Launch Quarkus | ||
| exec "$JAVA_CMD" ${POLARIS_JAVA_OPTS:-} -jar quarkus-run.jar "$@" | ||
| # Show the usage when no argument is provided | ||
| if [ "$#" -eq 0 ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
runtime/server/build.gradle.kts
Outdated
|
|
||
| // These are already provided transitively by polaris-runtime-service | ||
| // but we need them at compile time for CLI code | ||
| compileOnly(project(":polaris-core")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with @dimas-b these should be implementation for most of them. I would reorder them as below:
implementation(project(":polaris-core"))
implementation(project(":polaris-version"))
implementation(project(":polaris-api-management-service"))
implementation(project(":polaris-api-iceberg-service"))
implementation(project(":polaris-runtime-service"))
compileOnly("com.fasterxml.jackson.core:jackson-annotations")
implementation("io.quarkus:quarkus-picocli")There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
| * <ol> | ||
| * <li>(400) System properties: -D flags at JVM startup | ||
| * <li>(300) Environment variables | ||
| * <li>(260) External config/application-cli.properties: Profile-specific external config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned on the ML, I'm unsure whether we should mention the possibility of adding this profile-aware external config file, as it has very little added value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 Let's advise users to customize via the profile-neutral application.properties (and/or corresponding -D and env. vars).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user runs both the server and the CLI with the same Polaris binary of the same location, a shared application.properties applies to both use cases. In that setup, having a separate application-cli.properties still seems useful to capture CLI specific configuration that should not affect the server behavior. That separation feels reasonable and keeps the shared defaults clean while allowing targeted overrides for the CLI. For example, CLI specific configs like the following will be overwritten by application.properties
quarkus.banner.enabled=false
quarkus.log.level=WARN
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, profile-specific config works in conjunction with the profile-neutral config. In other words, application.properties is always loaded. This might be too much low-level details for end users to think about.
Even if all the code is bundled in the same Quarkus application, Server and Admin could still have distinct shell entry points and distinct application.properties files (each in its own directory). That would be my preference for the tar-based distribution.
Docker images can bundle anything that Polaris developers are ok with. In docker, users will override config via external mechanisms like env. variables. If a config map is used to define application.properties it will be specific to a particular runtime scenario anyway (Server or Admin, but not both).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
profile-specific config works in conjunction with the profile-neutral config
That's true, and I can confirm that's how it work today.
This might be too much low-level details for end users to think about.
This isn't a user-face doc. This is a comment in the source code. I think it should be fine to be here to provide complete view of how it works.
Even if all the code is bundled in the same Quarkus application, Server and Admin could still have distinct shell entry points and distinct application.properties files (each in its own directory). That would be my preference for the tar-based distribution.
Docker images can bundle anything that Polaris developers are ok with. In docker, users will override config via external mechanisms like env. variables. If a config map is used to define application.properties it will be specific to a particular runtime scenario anyway (Server or Admin, but not both).
I understand that these particular use cases may not require profile specific config files today. That said, this does not mean the scenarios I mentioned will never occur. Providing clear and explicit messaging still has value in that context. Even if a user never actively uses External config/application-cli.properties as a profile specific external config, having a clear understanding of how it works can be important when diagnosing or debugging unexpected behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the last minute comment here, but I wonder if it might make sense to keep the runtime/admin module as a home for Admin code, but not build a Quarkus app from it. The runtime/server module will then import runtime/admin and we end up with one Quarkus app both for the Server and Admin Tool... WDYT?
My rationale for keeping the runtime/admin module is just better code isolation at compile time. The runtime/server module is mostly an assembly descriptor, ATM it does not have any feature code. It might be preferable to keep it this way to allow simpler reuse of feature code from their dedicated modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, that's actually a nice idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the appeal of this approach, but I worry it may dismiss some of the key benefits of the current refactor(we will need a few common modules to enable a separate admin module), and make the dependency structure less clearer. Please note that, the CLI will need ServiceProvider to work now.
It also makes testing a bit awkward. Tests that are specific to the CLI behavior would have to depend on the default and service module just to pick up application-cli and application properties , which feels indirect and less explicit. For those reasons, I think the current direction still has advantages in terms of modularity, clarity, and test ergonomics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree on "test ergonomics" as an advantage in the current diff of this PR, but I do not think "modularity" is better - that's exactly what I meant to highlight in my comment above :)
IMHO, better modularity is preferable to "test ergonomics".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing the admin tool could follow the same approach as testing OPA (which is not monolithic with the server, but a pure puglin)... WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need a few common modules to enable a separate admin module. I believe this is one of areas we used to struggle with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of modularity, splitting functionalities across multiple modules does not automatically improve modularity. In many cases it does the opposite. It makes the dependency graph harder to reason about, and forces consumers and tests to pull in modules that exist only to host a thin slice of logic. I think good modularity is about cohesion and clear ownership. A module should group functionality that changes together and represents a meaningful boundary. And I'm not a fan of how we layout OPA modules.
In practice, over splitting often trades real modularity for superficial structure, while introducing costs in test ergonomics, dependency clarity, and mental overhead. Keeping related behavior together, even if it is small, is often the more modular choice. I have mentioned that we have to keep introducing new modules like runtime/common, runtime/test-common, runtime/distribution, they are the side effect of over splitting, which can be avoided in the beginning.

Please check the motivation here, https://lists.apache.org/thread/fs7j81kv2kn0wsh05412yk6pp7w7r5nz
Checklist
CHANGELOG.md(if needed)site/content/in-dev/unreleased(if needed)