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

Move CRD defaulting helpers outside of pkg/apis #138

Merged

Conversation

julianKatz
Copy link
Contributor

@julianKatz julianKatz commented Sep 23, 2021

In the building of gator github.com/willbeason found that the usage of
a shared Scheme amongst multiple sub-packages of pkg/apis/templates was
not thread safe. An internal map within the Scheme was experiencing a
simultaneous read and write.

Instantiating the scheme in a super-package and using it in the
sub-packages required the creation of a circular dependency, as the
super-package needed the contents of the sub-package to create a
functioning scheme that could convert between sub-package types. This
was previously solved by adding sub-package contents to the scheme at
scheme-usage-time, but this yielded the race condition on the map.

This PR moves most of the core logic into a separate package: pkg/schema

To prevent a circular dependency, a *runtime.Scheme is passed from
consumer packages to this new package's function call.

These schemes are instantiated once in the consumer packages and the
output of pkg/schema is stored at consumer package init() time to
prevent unnecessary re-calculation.

Fixes #137

Signed-off-by: juliankatz [email protected]

@codecov-commenter
Copy link

codecov-commenter commented Sep 23, 2021

Codecov Report

Merging #138 (e4875f5) into master (2924b2c) will decrease coverage by 0.18%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #138      +/-   ##
==========================================
- Coverage   42.39%   42.21%   -0.19%     
==========================================
  Files          49       46       -3     
  Lines        2951     2966      +15     
==========================================
+ Hits         1251     1252       +1     
- Misses       1321     1330       +9     
- Partials      379      384       +5     
Flag Coverage Δ
unittests 42.21% <ø> (-0.19%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...works/constraint/pkg/apis/templates/v1/defaults.go 44.44% <0.00%> (-11.12%) ⬇️
.../constraint/pkg/apis/templates/v1beta1/defaults.go 44.44% <0.00%> (-11.12%) ⬇️
...constraint/pkg/apis/templates/v1alpha1/defaults.go 44.44% <0.00%> (-11.12%) ⬇️
...eworks/constraint/pkg/apis/templates/v1/helpers.go 0.00% <0.00%> (ø)
...s/constraint/pkg/apis/templates/v1beta1/helpers.go 0.00% <0.00%> (ø)
.../constraint/pkg/apis/templates/v1alpha1/helpers.go 0.00% <0.00%> (ø)
...eworks/constraint/pkg/apis/templates/test_fakes.go
...meworks/constraint/pkg/apis/templates/transform.go
...traint/pkg/apis/templates/zz_generated.defaults.go
...eworks/constraint/pkg/apis/templates/crd_schema.go
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2924b2c...e4875f5. Read the comment docs.

Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

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

LGTM

In the building of `gator` github.com/willbeason found that the usage of
a shared Scheme amongst multiple sub-packages of pkg/apis/templates was
not thread safe.  An internal map within the Scheme was experiencing a
simultaneous read and write.

Instantiating the scheme in a super-package and using it in the
sub-packages required the creation of a circular dependency, as the
super-package needed the contents of the sub-package to create a
functioning scheme that could convert between sub-package types.  This
was previously solved by adding sub-package contents to the scheme at
scheme-usage-time, but this yielded the race condition on the map.

This PR moves most of the core logic into a separate package: pkg/schema

To prevent a circular dependency, a *runtime.Scheme is passed from
consumer packages to this new package's function call.

These schemes are instantiated once in the consumer packages and the
output of pkg/schema is stored at consumer package init() time to
prevent unnecessary re-calculation.

Fixes open-policy-agent#137

Signed-off-by: juliankatz <[email protected]>
Copy link
Member

@sozercan sozercan left a comment

Choose a reason for hiding this comment

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

LGTM

@julianKatz julianKatz merged commit f653a9c into open-policy-agent:master Oct 1, 2021
@julianKatz julianKatz deleted the threadsafe-toversionless branch October 1, 2021 19:23
julianKatz added a commit to julianKatz/frameworks that referenced this pull request Oct 5, 2021
PR open-policy-agent#138 introduced a bug: the type conversion functions required by the
Scheme for use in the ToVersionless functions of the v1, v1beta1,
v1alpha1 packages were missing.  This manifested itself as an error in
Gatekeeper:

"unable to convert template: converting (v1beta1.ConstraintTemplate) to
(templates.ConstraintTemplate): unknown conversion"

This problem was due to the ordering of init() functions.  init
functions are called according to the lexicographic ordering of their
containing functions. zz_generated.conversion.go registers the
conversion functions with the scheme, but did so after the init()
function previously held in defaults.go due to the aforementioned
ordering.

Rather than hack this ordering to ensure a correctly populated
`localSchemeBuilder`, this PR makes a schemeBuilder with the explicit
purpose of using it in the Scheme that's used in ToVersionless.  This
decouples the scheme from the ordering of init() funcs, resolving the
issue.

Signed-off-by: juliankatz <[email protected]>
julianKatz added a commit to julianKatz/frameworks that referenced this pull request Oct 5, 2021
PR open-policy-agent#138 introduced a bug: the type conversion functions required by the
Scheme for use in the ToVersionless functions of the v1, v1beta1,
v1alpha1 packages were missing.  This manifested itself as an error in
Gatekeeper:

"unable to convert template: converting (v1beta1.ConstraintTemplate) to
(templates.ConstraintTemplate): unknown conversion"

This problem was due to the ordering of init() functions.  init
functions are called according to the lexicographic order of their
containing files. zz_generated.conversion.go registers the conversion
functions with the scheme, but did so after the init() function
previously held in defaults.go due to the aforementioned ordering.  This
left the Scheme used in ToVersionless without the conversion functions
it was expected to have.

Rather than hack this ordering to ensure a correctly populated
`localSchemeBuilder`, this PR makes a schemeBuilder with the explicit
purpose of using it in the Scheme that's used in ToVersionless.  This
decouples the scheme from the ordering of init() funcs, resolving the
issue.

This PR also adds unit tests for each of the ToVersionless funcs,
ensuring such a problem won't happen again.

Signed-off-by: juliankatz <[email protected]>
julianKatz added a commit that referenced this pull request Oct 12, 2021
PR #138 introduced a bug: the type conversion functions required by the
Scheme for use in the ToVersionless functions of the v1, v1beta1,
v1alpha1 packages were missing.  This manifested itself as an error in
Gatekeeper:

"unable to convert template: converting (v1beta1.ConstraintTemplate) to
(templates.ConstraintTemplate): unknown conversion"

This problem was due to the ordering of init() functions.  init
functions are called according to the lexicographic order of their
containing files. zz_generated.conversion.go registers the conversion
functions with the scheme, but did so after the init() function
previously held in defaults.go due to the aforementioned ordering.  This
left the Scheme used in ToVersionless without the conversion functions
it was expected to have.

Rather than hack this ordering to ensure a correctly populated
`localSchemeBuilder`, this PR makes a schemeBuilder with the explicit
purpose of using it in the Scheme that's used in ToVersionless.  This
decouples the scheme from the ordering of init() funcs, resolving the
issue.

This PR also adds unit tests for each of the ToVersionless funcs,
ensuring such a problem won't happen again.

Signed-off-by: juliankatz <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ToVersionless should only call add to scheme once in a program's lifetime
5 participants