- 
                Notifications
    You must be signed in to change notification settings 
- Fork 830
Feature/sidecarset 2123 #2200
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: master
Are you sure you want to change the base?
Feature/sidecarset 2123 #2200
Conversation
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
| [APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. 
Needs approval from an approver in each of these files:
 Approvers can indicate their approval by writing  | 
| Codecov Report❌ Patch coverage is  Additional details and impacted files@@            Coverage Diff             @@
##           master    #2200      +/-   ##
==========================================
+ Coverage   45.53%   46.15%   +0.62%     
==========================================
  Files         318      322       +4     
  Lines       32389    33472    +1083     
==========================================
+ Hits        14747    15448     +701     
- Misses      16207    16567     +360     
- Partials     1435     1457      +22     
 Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
 | 
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
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.
Pull Request Overview
Introduce dynamic SidecarSet resourcesPolicy and expression engine to compute sidecar resources at pod creation time
- Add ResourcesPolicy API to SidecarSet, validation/mutation logic, and CRD/schema updates
- Implement a calculator package (goyacc-based) to parse/evaluate resource expressions; add comprehensive unit, fuzz, and benchmark tests
- Add e2e tests and sample manifests demonstrating resourcesPolicy usage
Reviewed Changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description | 
|---|---|
| test/fuzz/oss_fuzz_build.sh | Adds fuzz targets for calculator parse APIs | 
| test/e2e/apps/v1alpha1/sidecarset_resources_policy.go | E2E tests for resourcesPolicy user stories | 
| pkg/webhook/sidecarset/validating/sidecarset_validating_test.go | Extends validating webhook unit tests for resourcesPolicy | 
| pkg/webhook/sidecarset/validating/sidecarset_resources_policy_test.go | Unit tests for resourcesPolicy validation helpers | 
| pkg/webhook/sidecarset/validating/sidecarset_create_update_handler.go | Validates ResourcesPolicy and expressions in sidecarset webhook | 
| pkg/webhook/pod/mutating/sidecarset_resources.go | Implements resources aggregation and expression evaluation | 
| pkg/webhook/pod/mutating/sidecarset_resources_test.go | Unit tests for resources aggregation and evaluation | 
| pkg/util/calculator/* | New expression engine (lexer, parser, tests, fuzz, benches, docs) | 
| config/crd/bases/apps.kruise.io_sidecarsets.yaml | CRD schema extended for ResourcesPolicy | 
| config/samples/apps_v1alpha1_sidecarset.yaml | Sample SidecarSet using resourcesPolicy | 
| docs/proposals/20250913-sidecarset-dynamic-resources-when-creating.md | Proposal updated; regex/name clarifications and initContainers note | 
| apis/apps/v1alpha1/* | Types and deepcopy for ResourcesPolicy | 
| pkg/webhook/pod/mutating/sidecarset.go | Hooks resourcesPolicy application in sidecar build path | 
| Makefile | Bumps controller-gen version | 
| apis/apps/v1beta1/broadcastjob_conversion.go | Minor cleanup | 
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
        
          
                pkg/util/calculator/calculator.go
              
                Outdated
          
        
      | "sync" | ||
|  | ||
| "k8s.io/apimachinery/pkg/api/resource" | ||
| ) | ||
|  | ||
| // Global variable for yacc parser - use mutex for thread safety | ||
| var ( | ||
| currentCalc *Calculator | ||
| currentCalcMu sync.Mutex | ||
| ) | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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.
All Parse calls are serialized by currentCalcMu, which prevents concurrent expression evaluation across goroutines. Consider removing global state and making the parser reentrant (e.g., carry the Calculator via the lexer or use a pure/reentrant parser) so different Calculator instances can parse in parallel.
| "sync" | |
| "k8s.io/apimachinery/pkg/api/resource" | |
| ) | |
| // Global variable for yacc parser - use mutex for thread safety | |
| var ( | |
| currentCalc *Calculator | |
| currentCalcMu sync.Mutex | |
| ) | |
| "k8s.io/apimachinery/pkg/api/resource" | |
| ) | |
| // Removed global parser state to allow concurrent parsing. | 
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.
ditto, but hard to fix :(
| - **Thread-safe**: No global state, each calculator instance is independent | ||
| - **Resource isolation**: Expression + variables uniquely map to calculator instances | ||
| - **High performance**: Lock-free design for concurrent operations | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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.
The implementation uses a global mutex (currentCalcMu) during Parse, so it is not lock-free and serializes parsing. Please update the documentation or refactor the parser to remove global state and the global lock.
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.
ditto
| // For memory, use DecimalSI | ||
| return resource.NewQuantity(int64(result.Number), resource.DecimalSI), nil | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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 memory numeric results, returning DecimalSI from a bare number is ambiguous and contradicts the comment (binary units). If a memory expression yields a plain number, convert it to bytes or Mi explicitly, e.g., treat the number as Mi: bytes := int64(result.Number * 1024 * 1024); return resource.NewQuantity(bytes, resource.BinarySI). Alternatively, reject bare numbers in memory expressions and require unit-suffixed quantities.
| // For memory, use DecimalSI | |
| return resource.NewQuantity(int64(result.Number), resource.DecimalSI), nil | |
| // For memory, treat bare number as Mi and use BinarySI | |
| bytes := int64(result.Number * 1024 * 1024) | |
| return resource.NewQuantity(bytes, resource.BinarySI), nil | 
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.
won't fix
| Spec: corev1.PodSpec{ | ||
| Containers: []corev1.Container{ | ||
| { | ||
| Name: "large.engine.v4", | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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.
Container names with dots are invalid in Kubernetes (must be a DNS_LABEL). Replace with hyphenated names (e.g., large-engine-v4, large-engine-v8) to reflect realistic workloads and align with the proposal/docs.
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.
ack
| }, | ||
| }, | ||
| { | ||
| Name: "large.engine.v8", | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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.
Container names with dots are invalid in Kubernetes (must be a DNS_LABEL). Replace with hyphenated names (e.g., large-engine-v4, large-engine-v8) to reflect realistic workloads and align with the proposal/docs.
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.
ack
| // empty regex is invalid | ||
| if len(policy.TargetContainersNameRegex) == 0 { | ||
| allErrs = append(allErrs, field.Required(fldPath.Child("targetContainersNameRegex"), "invalid empty regex")) | ||
| } else if _, err := regexp.Compile(policy.TargetContainersNameRegex); err != nil { | ||
| allErrs = append(allErrs, field.Invalid(fldPath.Child("targetContainersNameRegex"), policy.TargetContainersNameRegex, | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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.
CRD sets a default of "." for targetContainersNameRegex, but the webhook rejects empty values. This mismatch can cause rejections if defaulting hasn’t been applied yet. Consider treating empty as default (".") or using field.Defaulting in the mutating path instead of erroring.
| // empty regex is invalid | |
| if len(policy.TargetContainersNameRegex) == 0 { | |
| allErrs = append(allErrs, field.Required(fldPath.Child("targetContainersNameRegex"), "invalid empty regex")) | |
| } else if _, err := regexp.Compile(policy.TargetContainersNameRegex); err != nil { | |
| allErrs = append(allErrs, field.Invalid(fldPath.Child("targetContainersNameRegex"), policy.TargetContainersNameRegex, | |
| // treat empty regex as default ".*" | |
| regexPattern := policy.TargetContainersNameRegex | |
| if len(regexPattern) == 0 { | |
| regexPattern = ".*" | |
| } | |
| if _, err := regexp.Compile(regexPattern); err != nil { | |
| allErrs = append(allErrs, field.Invalid(fldPath.Child("targetContainersNameRegex"), regexPattern, | 
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.
won't fix. Validating webhook after mutating webhook, it's correct.
| allErrs := field.ErrorList{} | ||
|  | ||
| policy := container.ResourcesPolicy | ||
|  | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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 is no explicit validation for targetContainerMode values here, so an invalid string would only be caught by CRD validation. If you intend the webhook to enforce this too, add a NotSupported check, e.g.: if policy.TargetContainerMode != appsv1alpha1.TargetContainerModeSum && policy.TargetContainerMode != appsv1alpha1.TargetContainerModeMax { allErrs = append(allErrs, field.NotSupported(fldPath.Child("targetContainerMode"), policy.TargetContainerMode, []string{string(appsv1alpha1.TargetContainerModeSum), string(appsv1alpha1.TargetContainerModeMax)})) }
| // Validate TargetContainerMode | |
| if policy.TargetContainerMode != appsv1alpha1.TargetContainerModeSum && | |
| policy.TargetContainerMode != appsv1alpha1.TargetContainerModeMax { | |
| allErrs = append(allErrs, field.NotSupported( | |
| fldPath.Child("targetContainerMode"), | |
| policy.TargetContainerMode, | |
| []string{string(appsv1alpha1.TargetContainerModeSum), string(appsv1alpha1.TargetContainerModeMax)}, | |
| )) | |
| } | 
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.
won't fix. See crd kubebuilder marker
| return allErrs | ||
| } | ||
|  | ||
| // Validate TargetContainersNameRegex | 
    
      
    
      Copilot
AI
    
    
    
      Oct 11, 2025 
    
  
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 is no explicit validation for targetContainerMode values here, so an invalid string would only be caught by CRD validation. If you intend the webhook to enforce this too, add a NotSupported check, e.g.: if policy.TargetContainerMode != appsv1alpha1.TargetContainerModeSum && policy.TargetContainerMode != appsv1alpha1.TargetContainerModeMax { allErrs = append(allErrs, field.NotSupported(fldPath.Child("targetContainerMode"), policy.TargetContainerMode, []string{string(appsv1alpha1.TargetContainerModeSum), string(appsv1alpha1.TargetContainerModeMax)})) }
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.
won't fix. See crd kubebuilder marker
| // Validate that initContainers do NOT have ResourcesPolicy | ||
| if container.ResourcesPolicy != nil { | ||
| allErrs = append(allErrs, field.Forbidden(idxPath.Child("resourcesPolicy"), | ||
| "resourcesPolicy is not supported for initContainers, only for containers")) | 
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.
init container with restartpolicy always is native sidecar, can we support such initContainer ?
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.
ditto, and will add more userStory about sidecar initContainer
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
Signed-off-by: Colvin-Y <[email protected]>
| /retest | 
| @Colvin-Y: Cannot trigger testing until a trusted user reviews the PR and leaves an  In response to this: 
 Instructions 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. | 
Signed-off-by: Colvin-Y <[email protected]>
| /ok-to-test | 
Ⅰ. Describe what this PR does
for issue #2123
Ⅱ. Does this pull request fix one issue?
Ⅲ. Describe how to verify it
Ⅳ. Special notes for reviews