chore(migration): generic store for migrations#7382
chore(migration): generic store for migrations#7382dashrews78 wants to merge 10 commits intomasterfrom
Conversation
|
Images are ready for the commit at afd4fd9. To use with deploy scripts, first |
rhybrillou
left a comment
There was a problem hiding this comment.
At first glance, the changes seem to introduce a copy of the generic store with the following changes:
- calls to metrics monitoring are removed
- Scoped access control checks are removed
Technically, the generated metrics functions could be replaced by an empty pass-through function.
On the Scoped access control side, I'd rather be in favour of using sac.WithAllAccess(ctx) in the migrations. That would leave room for some foreseeable changes to the way stores do work (the SAC checks could be moved from the generic stores further down to the SQL query generator).
The idea with the copy was to strip out stuff the migrations didn't need while also isolating the migrations from changes to the generic store so that we would be more intentional about what was included. Regarding SAC, the migrations do run with |
93a3093 to
afd4fd9
Compare
rhybrillou
left a comment
There was a problem hiding this comment.
Thank you for this great piece of work.
I really like the idea of auto-generating the store files for migrations. This will definitely improve the developer experience when writing data migrations.
I think the migration management experience improvement could be achieved with less code duplication (details as to why and how follow).
The recent changes in pkg/search/postgres/store.go move the access control checks of the read and delete functions down to pkg/search/postgres/common.go and pkg/search/postgres/common.go.
After this, the remaining changes between the migrator/migrations/postgreshelper/store.go file and pkg/search/postgres/store.go are:
- removal of the metrics collection logic (in store struct, constructor and internal functions)
- removal of the operation type from the acquireConn function and function calls
- removal of the access-control related elements and logic (in store struct, constructor as well as helper and Upsert* functions)
- small differences to the query passed down to the functions from
pkg/search/postgres/common.go(search.ConjunctionQuerynot removed where only one argument remains ornilvssearch.EmptyQuery())
The migration_store.go.tpl file in tools/generate-helpers/pg-table-bindings also has few changes compared to the store.go.tpl file:
- removal of the metrics collection functions
- removal of the access-control related elements
The time metrics collection functions could be replaced with empty pass-through functions in the generated code in the case of migration.
The access control checks will be there anyway for Walk, Count and Get* functions, and will therefore require the migrations to use contexts with elevated permissions. The elevated-permission context could be crafted in a way that the access control checks in the Upsert* functions would pass anyway.
I think using the standard store.go.tpl template with minor adjustments covering the migration-related cases would significantly reduce the need for code duplication here.
| to the `CurrentDBVersionSeqNum` of the release immediately following the release that cannot tolerate the change. | ||
| For example, in 4.2 a column `column_v2` is added to replace the `column_v1` column in 4.1. All the code from 4.2 | ||
| 2. If using the optional `STORE_OBJECT` parameter, generate the migration stores with the following command: | ||
| `gogen -run pg-table-bindings` |
There was a problem hiding this comment.
Should the command be run in the migration directory, in the directory where the gen.go file was generated, or in the directory where the code was cloned ? In case it is the clone directory, are there command line options to specify the directory in which the gen.go file is ?
|
|
||
| // Exists tells whether the ID exists in the store. | ||
| func (s *GenericStore[T, PT]) Exists(ctx context.Context, id string) (bool, error) { | ||
| q := search.ConjunctionQuery( |
There was a problem hiding this comment.
I think the search.ConjunctionQuery wrapper here is not needed anymore.
| func (s *GenericStore[T, PT]) Count(ctx context.Context) (int, error) { | ||
| var query *v1.Query | ||
|
|
||
| return searcher.RunCountRequestForSchema(ctx, s.schema, query, s.db) |
There was a problem hiding this comment.
nit: query here could be replaced by search.EmptyQuery().
|
|
||
| // Get returns the object, if it exists from the store. | ||
| func (s *GenericStore[T, PT]) Get(ctx context.Context, id string) (PT, bool, error) { | ||
| q := search.ConjunctionQuery( |
There was a problem hiding this comment.
nit: no need to wrap with search.ConjunctionQuery
| q := search.ConjunctionQuery( | ||
| query, | ||
| ) | ||
| q.Pagination = pagination |
There was a problem hiding this comment.
nit: no need for the overhead of using ConjunctionQuery and propagating pagination information when any.
| // - remove any unused function from the copied store files (the minimum for the public API should contain Walk, UpsertMany, DeleteMany) | ||
| // - remove the scoped access control code from the copied store files | ||
| // - remove the metrics collection code from the copied store files | ||
| // - remove the gen.go file generated in ../{OBJECT}/store |
There was a problem hiding this comment.
(repeat for all types impacted by the migration).
| SingletonStore: props.SingletonStore, | ||
| BatchSize: props.MigrationBatchSize, | ||
| } | ||
| if props.MigrateSeq != 0 { |
There was a problem hiding this comment.
Although not directly related to the change at hand, I think it the generation of the stores for the initial migration to postgres could be removed from this generator.
|
|
||
| // New returns a new Store instance using the provided sql instance. | ||
| func New(db postgres.DB) Store { | ||
| return postgreshelper.NewGenericStore{{ if .PermissionChecker }}WithPermissionChecker{{ end }}[storeType, *storeType]( |
There was a problem hiding this comment.
The postgreshelper package has no WithPermissionChecker variant of the constructor, which would be the same as the base constructor once the access-control related elements are removed.
|
That's great info. Thanks. I'm HOPING I can get back to this and finish it in the near future. Especially since the SAC changes were moved. Should simplify things. |
|
@dashrews78: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Description
This is a take on a generic store for migrations. The tooling from the
make bootstrap_migrationtarget was updated to take in a list of storage protos. For each storage proto it will create agen.gothat will create a storegogen -run pg-table-bindingsis executed. The store being generic will allow for the previous data to be retrieved as those functions simply return the protos (or IDs) generically. The generated store will contain the insert logic for the latest proto and as such will insert data in the form the current release understands. See the testing section below to look at an example.I made a copy for the migration to provide a level of isolation. If we decide we can simply use the generic store in
pkg/search/postgresI would recommend we do that under additional tech debt tickets. Since currently we cannot use a copy of a store for a migration easily due to the move to the generic store. Similarly if we decide we want to handle sac in migrations that would be another issue to handle as tech debt. I simply removed all the SAC checks in the copy of the store for the migrator.This also includes any necessary changes for ROX-17423, ROX-18778.
Checklist
- [ ] Evaluated and added CHANGELOG entry if required- [ ] Determined and documented upgrade steps- [ ] Documented user facing changes (create PR based on [openshift/openshift-docs](https://github.com/openshift/openshift-docs) and merge into rhacs-docs)If any of these don't apply, please comment below.
Testing Performed
Created #7387 where I created
m_188_to_m_189_test_generic_exampleto demonstrate the use of the generic store and executed the migration test. (Ignore them_187_to_m_188_add_nftables_to_policyas that was my first example attempt)