Warn when legacy .s2i/bin/assemble scaffolding is detected#3584
Warn when legacy .s2i/bin/assemble scaffolding is detected#3584Ankitsinghsisodya wants to merge 2 commits intoknative:mainfrom
Conversation
Prior to knative#3436, func wrote S2I scaffolding for go/python to <func-root>/.s2i/bin/assemble. It now lives at .func/build/bin/assemble. The stale file can interfere with other builders (e.g. pack erroneously detects the assemble script). Add WarnIfLegacyS2IScaffolding helper in pkg/s2i that checks only scaffolded runtimes (go/python) and only the exact file func generated, so user-managed .s2i directories are not flagged. Call it from both the local Build() path and the remote PipelinesProvider.Run() path so the warning is emitted regardless of how the function is built. Fixes knative#3452
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Ankitsinghsisodya The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @Ankitsinghsisodya. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Tip We noticed you've done this a few times! Consider joining the org to skip this step and gain Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. 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-sigs/prow repository. |
There was a problem hiding this comment.
Pull request overview
Adds a centralized warning for legacy func-generated S2I scaffolding (<func-root>/.s2i/bin/assemble) so users are alerted when stale files may interfere with current builds/deployments after the scaffolding move to .func/build.
Changes:
- Added
WarnIfLegacyS2IScaffoldinghelper inpkg/s2ito detect the legacy.s2i/bin/assembleand emit a warning. - Wired the warning into both local S2I builds (
Builder.Build) and remote Tekton pipeline runs (PipelinesProvider.Run). - Added table-driven unit coverage to ensure warning behavior matches scaffolded vs non-scaffolded runtimes.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| pkg/s2i/scaffolder.go | Introduces the legacy scaffolding detection + warning helper. |
| pkg/s2i/builder.go | Invokes the warning during local S2I builds. |
| pkg/s2i/builder_test.go | Adds tests validating warning emission/suppression behavior. |
| pkg/pipelines/tekton/pipelines_provider.go | Invokes the warning during remote pipeline runs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pkg/s2i/scaffolder.go
Outdated
| legacyAssemble := filepath.Join(f.Root, ".s2i", "bin", "assemble") | ||
| if _, err := os.Stat(legacyAssemble); err == nil { |
There was a problem hiding this comment.
The docstring says this check is scoped to “the exact file func generated” so user-managed .s2i dirs aren’t flagged, but the implementation only checks for existence of .s2i/bin/assemble. This will warn even if the user intentionally created their own assemble script. Either update the comment to match the behavior, or (preferably) read the file and verify it matches the known legacy func-generated script content (e.g., compare against GoAssembler/PythonAssembler) before warning.
| legacyAssemble := filepath.Join(f.Root, ".s2i", "bin", "assemble") | |
| if _, err := os.Stat(legacyAssemble); err == nil { | |
| expectedAssemble, err := assembler(f) | |
| if err != nil || expectedAssemble == "" { | |
| return | |
| } | |
| legacyAssemble := filepath.Join(f.Root, ".s2i", "bin", "assemble") | |
| content, err := os.ReadFile(legacyAssemble) | |
| if err != nil { | |
| return | |
| } | |
| if string(content) == expectedAssemble { |
pkg/s2i/builder_test.go
Outdated
| oldStderr := os.Stderr | ||
| r, w, err := os.Pipe() | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| os.Stderr = w | ||
|
|
||
| i := &mockImpl{BuildFn: func(cfg *api.Config) (*api.Result, error) { return nil, nil }} | ||
| b := s2i.NewBuilder(s2i.WithImpl(i), s2i.WithDockerClient(mockDocker{})) | ||
| buildErr := b.Build(t.Context(), f, nil) | ||
|
|
||
| w.Close() | ||
| os.Stderr = oldStderr | ||
|
|
||
| var buf bytes.Buffer | ||
| if _, err := io.Copy(&buf, r); err != nil { | ||
| t.Fatal(err) |
There was a problem hiding this comment.
This test redirects the process-global os.Stderr but doesn’t use t.Cleanup/defer to guarantee restoration (and pipe closure) on early failures/panics. It also never closes the read end of the pipe, which can leak FDs across the test suite. Use t.Cleanup to restore os.Stderr and close both pipe ends, and avoid leaving global state changed if the test fails mid-way.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3584 +/- ##
==========================================
+ Coverage 56.24% 56.30% +0.05%
==========================================
Files 180 180
Lines 20465 20528 +63
==========================================
+ Hits 11511 11558 +47
- Misses 7755 7765 +10
- Partials 1199 1205 +6
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:
|
|
I think we could actually run the warning on every deployment, because user mightve used s2i, then switched to a different builder. This would persist the .s2i/ directory in the function. Granted there was a bug where running w/ s2i and subsequently running w/ pack a different, cryptic error would occur becuase of how pack works. (this was the side-effect). Either every deploy or every build (deploy uses build under the hood, that is the client function Remote deployment keeps the call but would not have to import the s2i when the function is moved (see below) Scoping only to scaffolded runtimes (go/python) looks correct to me. The warn function itself could live in the |
Per review feedback on knative#3584, the warning helper now lives in pkg/functions as a standalone WarnIfLegacyS2IScaffolding and is invoked from Client.Build, so it fires for every build (and therefore every local deploy) regardless of which builder the user switched to. The Tekton pipelines provider keeps its own call for remote deploys (which don't go through Client.Build) and no longer needs to import pkg/s2i. The s2i builder's redundant call is removed. The test moves to pkg/functions and exercises the helper directly.
|
Thanks for the review @gauron99 sir! Pushed an update that does exactly this:
Kept the |
Changes
WarnIfLegacyS2IScaffoldinghelper inpkg/s2ithat detects the func-generated legacy.s2i/bin/assemblefile and prints a warning to stderrBuild()path (pkg/s2i/builder.go) and the remote pipelineRun()path (pkg/pipelines/tekton/pipelines_provider.go) so it fires regardless of how the function is built or deployed/kind enhancement
Fixes #3452
Release Note
Docs