Skip to content
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

Fix the generation init-tasks by database migration on Kubernetes #33116

Closed
wants to merge 3 commits into from

Conversation

Sgitario
Copy link
Contributor

@Sgitario Sgitario commented May 4, 2023

These changes include:
- Don't generate the init task for db migration if migrate at start is off:

The quarkus.[flyway or liquibase or liquibase-mongodb].enabled and quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start properties are runtime properties, so I have to create the following build time properties to read these values and allow users configurating it:

  • quarkus.[flyway or liquibase or liquibase-mongodb].generate-init-task with default value quarkus.[flyway or liquibase or liquibase-mongodb].enabled
  • quarkus.[flyway or liquibase or liquibase-mongodb].migrate-with-init-task with default value quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start

Plus, I've extended the coverage of these extensions with the K8s tests.

- Allow overriding generated init-container of extensions from user config (related to this comment)
- Change default image for init container waiters (necessary for OpenShift deployments) (related to this comment)

Each of these changes is included in an individual commit on purpose to ease up the review.

Fix #33097

@Sgitario
Copy link
Contributor Author

Sgitario commented May 4, 2023

Moreover, there is an outstanding issue that is fixed by #33086.

Sgitario added 3 commits May 4, 2023 14:13
The `quarkus.[flyway or liquibase or liquibase-mongodb].enabled` and `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start` properties are runtime properties, so I have to create the following build time properties to read these values and allow users configurating it:

- `quarkus.[flyway or liquibase or liquibase-mongodb].generate-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].enabled`
- `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-with-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start`

Plus, I've extended the coverage of these extensions with the K8s tests. 

Fix quarkusio#33097
To groundnuty/k8s-wait-for:no-root-v1.7.

Related to quarkusio#33097 (comment)
@quarkus-bot
Copy link

quarkus-bot bot commented May 4, 2023

Failing Jobs - Building a536cb9

Status Name Step Failures Logs Raw logs
✔️ JVM Tests - JDK 11
JVM Tests - JDK 17 Build Failures Logs Raw logs
JVM Tests - JDK 17 Windows Build ⚠️ Check → Logs Raw logs
JVM Tests - JDK 19 Build ⚠️ Check → Logs Raw logs

Full information is available in the Build summary check run.

Failures

⚙️ JVM Tests - JDK 17 #

- Failing: extensions/elytron-security-jdbc/deployment 
! Skipped: integration-tests/elytron-security-jdbc 

📦 extensions/elytron-security-jdbc/deployment

io.quarkus.elytron.security.jdbc.CustomRoleDecoderDevModeTest.testConfigChange line 66 - More details - Source on GitHub

java.lang.AssertionError: 
1 expectation failed.
Expected status code <200> but was <500>.

io.quarkus.elytron.security.jdbc.CustomRoleDecoderTest. - More details - Source on GitHub

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:704)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:395)

io.quarkus.elytron.security.jdbc.MinimalConfigurationTest. - More details - Source on GitHub

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:704)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:395)

io.quarkus.elytron.security.jdbc.MultipleDataSourcesTest. - More details - Source on GitHub

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:704)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:395)

io.quarkus.elytron.security.jdbc.MultipleQueriesConfigurationTest. - More details - Source on GitHub

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:704)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:395)

@Sgitario
Copy link
Contributor Author

Sgitario commented May 5, 2023

I think the test failures are unrelated.

@gsmet
Copy link
Member

gsmet commented May 5, 2023

@Sgitario is it something that should be backported to 3.0?

@Sgitario
Copy link
Contributor Author

Sgitario commented May 5, 2023

@Sgitario is it something that should be backported to 3.0?

The issue was introduced in #29026 which is part of Quarkus 3. So, yes, I'm adding the backport label.

matching.endInitContainer();
}

private boolean hasInitContainer(ContainerBuilder containerBuilder) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This predicate does not test the existence of a container, but wether a container has matching name. The name should probably change to match the functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will rename it

Copy link
Contributor

@iocanel iocanel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few objections that I'll summarize here.

  1. Introduced configuration is more fine grained than it needs to.
  2. We are defaulting build time configuration to runtime config values, which is weird.
  3. We implement multiple versions of decorators for not clear reason.

import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.PodSpecBuilder;

public abstract class AddInitContainerDecorator extends NamedResourceDecorator<PodSpecBuilder> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason for creating a new decorator, let alone 3.
If there is a technical reason why we do so, it should definitely need to be part of a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary to overwrite the hardcoded properties (image, command, args) of the init-containers using the standard properties: #33097 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need new decorators to do that. Existing decorators for setting image, command and args do already exist and should be used instead. We should limit the amount of overlapping decorators as its complicates predicting the order of things.

*
* The default value is `quarkus.liquibase-mongodb.migrate-at-start`.
*/
@ConfigItem(defaultValue = "${quarkus.liquibase-mongodb.migrate-at-start:false}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need two properties for doing pretty much the same thing.
One should be enough.

Also, I am not a big fan for having build time configuration defaulting to runtime values. This seems weird if not wrong.

Last, I am wondering if generateInitTask will is descriptive enough to let people understand this refers to kubernetes jobs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I am not a big fan for having build time configuration defaulting to runtime values. This seems weird if not wrong.

I'm not super happy with this either. Though, we're generating build time resources (the init-task resources) that is actually disabled by default (migrate-at-start property is disabled by default), and can be enabled/disabled at runtime.

Therefore, if users enable the migrate-at-start property at build time, then it means that they are likely to need the init-task when running the app in K8s, so I think it makes sense to me.

About having two properties, this extension can be enabled/disabled using two properties enabled and migrate-at-start, so having only one property is probably not enough. Also, adding a totally new build-time property will be unlikely to be used by users (because they are used to use the existing and well-known enabled and migrate-at-start properties).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migrate-at-start property is a runtime property and does not affect in any way the generation of kubernetes resources, so the property is redundant and needs to be removed. What the init container does should not be a concern of the part that is generating the Job.

About the default value I don't have a super strong opinion so let's see what others think.
@geoand @gsmet: We need your expert opinion: Is it ok to have a build time property with a default value that points to a runtime property?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty sure that won't work, but I'll have a look at this tomorrow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migration is enabled/disabled by runtime properties, and the generated Job to perform the migration has to be created/or not created at build time. So, here is the clash.

Is it ok to have a build time property with a default value that points to a runtime property?

It works as you can see with the new test cases I added as part of this pull request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migration is enabled/disabled by runtime properties, and the generated Job to perform the migration has to be created/or not created at build time. So, here is the clash.

Agree. There is a clash so we shouldn't tie the two together.

It works as you can see with the new test cases I added as part of this pull request.

The fact that this is indeed working is irrelevant. There is a clash as you already pointed out and we should better avoid it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works as you can see with the new test cases I added as part of this pull request.

The fact that this is indeed working is irrelevant. There is a clash as you already pointed out and we should better avoid it.

I don't see your point here: the test cases probe that the new build properties whose default values are taken from runtime properties work fine, but you say it's irrelevant?

The current pull request does address and avoids the current linked issue when using flyway / liquibase plus K8s/OpenShift extensions by using well-known properties. It's perfectly fine if you all don't like this solution and/or prefer adding a new build time property that users will need to learn to generate the init-task resources. But don't agree with you saying that the test cases are irrelevant or that the clashing problem is not addressed.

@Sgitario
Copy link
Contributor Author

Sgitario commented May 7, 2023

I have a few objections that I'll summarize here.

  1. Introduced configuration is more fine grained than it needs to.
  2. We are defaulting build time configuration to runtime config values, which is weird.
  3. We implement multiple versions of decorators for not clear reason.

I hope I've clarified and justified all the points here for further discussion.
I still think the requirement is valid because the initial solution introduces breaking changes. And the solution is correct enough, but let me know if you have something else in mind to overcome the linked issue.

@Sgitario
Copy link
Contributor Author

Sgitario commented May 8, 2023

Closing as per comment in #33097 (comment)

@Sgitario Sgitario closed this May 8, 2023
@quarkus-bot quarkus-bot bot added triage/invalid This doesn't seem right and removed triage/backport? labels May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Quarkus with liquibase on Kubernetes
4 participants