-
Notifications
You must be signed in to change notification settings - Fork 0
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
implement seed mechanism #4
Conversation
@shreddedbacon is there anything missing here? |
Need to set aside some time for a review |
@domcyrus can you rebase/merge main latest into this so the e2e action can run? |
I can't get this to work, I don't think the implementation is complete. The e2e tests don't have appear to have a test where a The seed example has If I update the secret to use
This is because the provider reference is missing?. I guess there is a missing step where the seed gets correctly checked against the available providers and will add the required reference. I think the seed logic should probably check if the requested scope + the hostname/port in the seed have a match, if so, add the provider reference For example, if i have the following providers
But then I want to create 2 Database requests to either use existing credentials that may exist, or have the controller create these credentials on the requested host:
Then I would expect that the The |
I'm on holiday this week. I'll have a look next week. |
@shreddedbacon I didn't want to make the seed mechanism depend on a provider but if you want this I can adapt the code to do that. |
I've updated the test files so that it does actually create a full test. Note that I didn't change anything in the code but the resulting secret and service do look fine for me: apiVersion: v1
items:
- apiVersion: v1
data:
database: c2VlZC1kYXRhYmFzZQ==
hostname: bXlzcWwtc2VydmljZS5teXNxbA==
password: c2VlZC1wYXNzd29yZA==
port: MzMwNg==
username: c2VlZC11c2VybmFtZQ==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"database":"c2VlZC1kYXRhYmFzZQ==","hostname":"bXlzcWwtc2VydmljZS5teXNxbA==","password":"c2VlZC1wYXNzd29yZA==","port":"MzMwNg==","username":"c2VlZC11c2VybmFtZQ=="},"kind":"Secret","metadata":{"annotations":{},"name":"mysql-seed-secret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2024-05-27T14:46:53Z"
name: mysql-seed-secret
namespace: default
resourceVersion: "1032"
uid: 4bb29c0a-7e5e-4d20-bdc1-f0eb585c78c1
type: Opaque Checking base64 values:
Therefore I'm not really sure why it shouldn't have worked for you... |
The main usage of the seed was primarily to make it easy for a Lagoon build to update references from an old Currently Lagoon and the dbaas operator provisions databases like so:
What we want is to use the new The result would be something like this:
All that the dbaas controller needs to do is:
|
I could create the seed secret fine. But when I created a I don't see anywhere obvious in the tests where the Edit: I think I see it now (github didn't refresh properly for me initially so I missed the last commit), I will have another run through when I get some more time |
@shreddedbacon as mentioned on slack I've merged the other two PRs and rebased it. Let me know if you need some more information on this PR. |
Yep, did you see my previous comment: #4 (comment) |
A sorry I see... This (#4) sounds like a good plan to me. I'll update the PR today. |
@shreddedbacon I've now implemented it in the way you've described above #4 |
@shreddedbacon let me know if you need more details about something or if something else is still missing. Thanks. |
After today discussion:
|
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 all good. Only concern I have is that a DatabaseRequest
that has fails to seed continues to be reconciled flooding the logs with reconcile errors.
This seems unnecessary. The DatabaseRequest
should also probably go into a failed
status that is easier to see
status:
conditions:
- lastTransitionTime: '2024-06-05T03:46:20Z'
message: >-
mysql db find connection from seed failed
reason: Failed
status: 'True'
internal/database/database.go
Outdated
@@ -112,6 +117,32 @@ func (ri *RelationalDatabaseImpl) Ping(ctx context.Context, dsn string, dbType s | |||
} | |||
|
|||
if err := db.PingContext(ctx); err != nil { | |||
if dbType == mysql { | |||
log.FromContext(ctx).Error(err, "Failed to ping MMMMMySQL database") |
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.
typo on MySQL
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.
Will remove... It was some leftover from some testing.
Regarding flooding the logs: The Another idea would be to not log anything if nothing in the seed has changed and the error in the status condition is related to the seed. In that case the I would vote to rather keep the current default runtime behavior which will solve handle the same error by increasing the time to retry. It will log a few times the same error at the beginning but later on it won't do that often anymore. I think this is a good behavior because it fixes issues automatically and plays nice with kubernetes eventual consistency concept.
I've added an additional Error status condition. |
I think this behaviour and lagoon are a bad combination generally. But I think we can be a bit smart about the things that retry and continue trying to reconcile until success, and things that are deemed a hard failure and to not retry them with. Some parts of a Lagoon build are more suited to a hard failure than a "wait for" condition, that's all. |
I understand. If we prefer to return success and not retry on an invalid or broken seed, that works fine for me. I was thinking that it might make sense to retry. For example, if a platform engineer is alerted, they could inspect the seed secret and fix it manually. In that case retrying would allow the system to automatically correct itself. Without retrying, the system will not have the opportunity to autocorrect. |
In theory this is fine. But it could end very badly if something is done incorrectly. In this case, if a seed fails it should not retry. The lagoon build will drop a warning and continue to use the If it was to continue to retry, and someone from platform stepped in and resolved the issue incorrectly, then it could potentially result in outages or downtimes. A failure to convert from Because of some very old bugs in Lagoon builds, there are some I'll have to put together documentation about how to recover from these situations though when we get closer to doing this within a build though, because it could impact opensource users as well as AIO directly. |
I've changed the code to not retry on specific seed errors. This triggered tests on seed to randomly fail, because of a race condition when creating the seed database. I've fixed it with a sleep. I think it makes a good example of why retries are useful. PS: I'll certainly remove the comments about the retry it is just to illustrate on why they might be useful. |
Since the sleep is only in the test suite to give the mysql pod time to start up for the test to run, then this is somewhat acceptable to me, I'm sure the test could also be refactored to ensure the pod is running though instead of an arbitrary sleep too. |
@shreddedbacon Is there anything else needed? |
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.
Did some quick verifications with emulating how a build may create the seed and request and this works great. The failure case with the seed is ideal for how Lagoon builds work to prevent unexpected behaviours.
Thanks Marco!
No description provided.