-
Notifications
You must be signed in to change notification settings - Fork 40.7k
Remove use of html/template in apiserver to avoid disabling dead code elimination #132177
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
Remove use of html/template in apiserver to avoid disabling dead code elimination #132177
Conversation
Hi @pgimalac. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. 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-sigs/prow repository. |
/ok-to-test @pgimalac i am curious, how did you find the issue and the fix? thanks! |
/are code-organization |
👋 @dims I think what made me aware of the issue in general is this talk https://www.youtube.com/watch?v=EkG177eRcco on the topic and this associated pull request in cobra spf13/cobra#1956. Over the past few months I've been actively working on enabling the optimization in the binaries from https://github.com/DataDog/datadog-agent, by fixing upstream dependencies when possible, or just removing them / forking them otherwise. In order to find for a given binary what is disabling the optimization, you can add For this specific change, here is the output of the tool: whydeadcode output
We can see that the problematic code is the use of template removed by this PR. |
Relevant discussion golang/go#72895 Are we not using all those reflection method in other places? @pgimalac can you add to the description what is the exact effective improvement on the apiserver binary? From current kind job in this pr
From another kind job in another pr
I can't see the difference To clarify, the problem seems to be the reflection method, is just that library uses them , so removing html template is necessary condition but not enough, as other libraries or code maybe using them |
I'm not familiar with the binaries generated in this repo so I can't say without looking into it further, but very likely this is not enough for your binaries, eg. I know go-cmp is used in this repo and it disables DCE (related issues: #104821, #130201, google/go-cmp#373). I can at least say that one of the binaries I work on imports code from I built the binary in |
Well it's not that bad, the changes needed to enable the optimization in
Building locally on Darwin arm64, the stripped binary I'd be happy to open PRs for each change, but unless you're open to using a fork of go-cmp, it's not that easy to get rid of (so you wouldn't be able to enable the optimization). |
I think is better to merge all changes together and some sort of regression test |
@aojea as I mentioned in my previous message, unless you're willing to use a fork of https://github.com/google/go-cmp (or to drop it entirely), the optimization can't be enabled for the Also in general I would argue in favor of doing those changes in separate PRs to keep things clean, eg. updating dependency has value in itself, even without considering the optimization. |
sorry, I was replying from mobile and didn't see the context,
forking go-cmp sounds problematic, updating deps that improve things sounds a good thing, although this final decision will be in the area-organization people, @liggitt and @dims best persons to judge My personal take on this optimization, is that without having a detection mechanism that prevents you to get bitten again by the same problem, using modified code to overcome it seems that the risk you take can not be guaranteed |
On my side in the datadog-agent repo we have CI to ensure that the various binaries we generate don't become bigger, so once the optimization is enabled it can't be accidentally disabled again (since that would add back dozens of MiB) I'd love to be able to enable the optimization for your binaries, but it likely will have to wait until #104821 is fixed somehow, or until they accept a fix upstream (feel free to comment on the issue by the way !) In any case I'd really like to be able to get this one change merged so that I can benefit from the optimization if you're fine with it |
I didn't know about that one... I just assumed the importer checker would be the easiest path. I'd probably wait to merge until we have a verify script ready (either using existing import tools or something else, and whether it's in this PR or a separate PR, but ready) |
@liggitt @pgimalac let's do the following here. I will rework later in a follow up PR diff --git a/cmd/kubeadm/app/cmd/util/join.go b/cmd/kubeadm/app/cmd/util/join.go
index cbf58238ab0c..feded1d06d75 100644
--- a/cmd/kubeadm/app/cmd/util/join.go
+++ b/cmd/kubeadm/app/cmd/util/join.go
@@ -19,7 +19,7 @@ package util
import (
"bytes"
"crypto/x509"
- "html/template"
+ "html/template" //nolint:depguard
"strings"
"k8s.io/client-go/tools/clientcmd"
diff --git a/hack/golangci.yaml b/hack/golangci.yaml
index 2306878a6bfe..94dcd95e711d 100644
--- a/hack/golangci.yaml
+++ b/hack/golangci.yaml
@@ -268,6 +268,8 @@ linters:
deny:
- pkg: "github.com/google/go-cmp/cmp"
desc: "cmp is allowed only in test files"
+ - pkg: "html/template"
+ desc: "template is allowed only in test files as it disables dead code elimination"
forbidigo:
analyze-types: true
forbid: |
@dims I pushed a commit with your suggestions 👍 |
/lgtm |
LGTM label has been added. Git tree hash: 1b03a93824b3404b96e857942c5bfa3c34943241
|
@pgimalac oops! forgot to mention there are 3 files in there where we have to add the
|
/lgtm 🤞🏾 |
LGTM label has been added. Git tree hash: f27d3417f6901334dab62239c7916c07df6abf3f
|
@dims One nolint was missing in |
@pgimalac if you want to squash the commits, that would be great as well. |
b469a08
to
40c7188
Compare
/approve |
LGTM label has been added. Git tree hash: bb27f89663a6f858735c232fb348d09b2b5941f8
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: dims, liggitt, pgimalac The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind bug
What this PR does / why we need it:
Replace the use of
html/template
inapiserver
with direct string manipulation.It avoids disabling dead code elimination for binaries importing this code*, in my case this single change makes a binary go from 155MiB to 117MiB (-25%).
The template is quite trivial so I don't feel like it makes the code much more complex.
*Note that this single change doesn't enable dead code elimination in the
kube-apiserver
binary, a few other changes are needed (see #132177 (comment) for details), in particular fixing or getting rid of https://github.com/google/go-cmp.Which issue(s) this PR is related to:
#130201: Note the same piece of code, but same issue.
Special notes for your reviewer:
Let me know if you want me to add tests around template rendering.
I believe the calls to
Write
andFprintf
can't fail, but I still checked the returned errors, let me know if I should remove that to simplify the code.Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.: