-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Pass serviceAccountToken to freezer service #11917
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
Conversation
Codecov Report
@@ Coverage Diff @@
## main #11917 +/- ##
==========================================
- Coverage 87.49% 87.46% -0.04%
==========================================
Files 196 196
Lines 9515 9531 +16
==========================================
+ Hits 8325 8336 +11
- Misses 917 921 +4
- Partials 273 274 +1
Continue to review full report at Codecov.
|
425d204
to
7f57704
Compare
7f57704
to
4556626
Compare
The test failures are for |
755360b
to
d62ccf3
Compare
4eb4b51
to
42dd50d
Compare
This one's ready now |
pkg/queue/concurrency_state.go
Outdated
return concurrencyStateRequest(endpoint, "resume") | ||
} | ||
|
||
type Token struct { |
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.
Might be worth using atomic.Value for this: https://pkg.go.dev/go.uber.org/atomic#Value
pkg/queue/concurrency_state_test.go
Outdated
// | ||
// tempFile := createTempTokenFile(logger) | ||
// defer os.Remove(tempFile.Name()) | ||
func createTempTokenFile(logger *zap.SugaredLogger) *os.File { |
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.
Would t.TempDir work here? That would automatically clean up the dir when the test exits. (We should avoid ioutil package for new code, all the methods now have equivalents elsewhere).
pkg/queue/concurrency_state.go
Outdated
refreshToken(&tokenCfg, tokenMountPath) | ||
go func() { | ||
for { | ||
time.Sleep(1 * time.Minute) |
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.
Rather than doing the token stuff here, what do you think about pulling it out in to the Pause and Resume request structs? They're already abstracting how the Handler should contact the endpoint, so it seems odd (to me) for Handler to have the token code rather than them (I'm imagining something like a type concurrencyStateRequest struct { token atomic.Value }
struct with Pause and Resume functions).
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.
It did cross my mind, though I was leaning towards having the Pause/Resume functions grab the refreshed token when called, rather than running a goroutine in the handler to keep it refreshed. I had a little nagging worry that getting the token in the pause/resume functions might end up grabbing the wrong value vs. getting it in the handler (though to be fair it was a fleeting thought and I didn't really pursue it too far). That said, let me give it another go.
(Figures that I juuuuust dropped the request struct from the previous PR 😄 )
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.
@julz before I go too far down the refactor train, would something like this be along these lines of what you're thinking?
type ConcurrencyEndpoint struct {
endpoint string
token atomic.Value
}
func (c ConcurrencyEndpoint) Pause() error { c.Request("pause") }
func (c ConcurrencyEndpoint) Resume() error { c.Request("resume") }
func (c ConcurrencyEndpoint) Request(request string) func() error { /* send request */ }
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.
Turns out the end of the line wasn't all that far away... got this added in the last batch of commits
pkg/queue/concurrency_state.go
Outdated
|
||
"go.uber.org/atomic" | ||
"go.uber.org/zap" | ||
) | ||
|
||
//nolint:gosec // Filepath, not hardcoded credentials | ||
const ConcurrencyStateTokenVolumeMountPath = "/var/run/secrets/tokens" | ||
const ConcurrencyStateTokenName = "state-token" | ||
const ConcurrencyStateToken = ConcurrencyStateTokenVolumeMountPath + "/" + ConcurrencyStateTokenName |
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.
these consts having to be exported and shared between pkg/deploy and pkg/queue are a bit sad, wonder if there's a way we could avoid that. What if we got the token path from an env variable? That seems a bit more decoupled and maybe a bit cleaner (this is how we used to handle a similar thing in the past where we looked for some info via the downward api).
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.
bump ^
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.
FWIW, exporting/sharing constant names seems to be a fairly common pattern to pass values to pkg/deploy (queue.Name and queue.RequestQueueDrainPath are passed this way, as well as several from networking). Would it make sense to convert them all to environmental variables (all meaning the QP ones)? If so, perhaps that would be better done in a separate PR.
If that's the route we want to go, for now I could either leave the CE constants where they are or move them to pkg/queue/constants.go
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.
I'm not really convinced queue.Name and queue.RequestQueueDrainPath (or the port related constants in networking) are a very good parallel here, since they're properties of the queue, not properties of how the queue is deployed. The main issue is that we're exporting three separate related constants, which makes the api of pkg/queue more complicated (and coupled) than it needs to be. If instead we passed the mounted location of the token, this would be a fair bit simpler and cleaner.
FWIW this is what we did both times we previously did a feature involving mounting a volume in QP (1, 2), and it seemed quite nice that way.
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.
Fair enough, was just checking if we should also update the other ones.
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.
done
pkg/queue/concurrency_state_test.go
Outdated
tempDir := t.TempDir() | ||
tokenFile := createTempTokenFile(logger, tempDir) |
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.
I think we can use os.WriteFile
here and drop createTempTokenFile
.
tempDir := t.TempDir() | |
tokenFile := createTempTokenFile(logger, tempDir) | |
tokenPath := filepath.Join(t.TempDir(), "secret") | |
if err := os.WriteFile(tokenPath, []byte("0123456789"), 0700); err != nil { | |
t.Fatal(err) | |
} |
pkg/queue/concurrency_state_test.go
Outdated
return tokenFile | ||
} | ||
|
||
func createConcurrencyEndpoint(e, m, t string) ConcurrencyEndpoint { |
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.
I think I'd convert this in to a NewConcurrencyEndpoint constructor so this is generally useful outside the test (and so consumers of the struct can't get themselves in trouble using it before the token has been stored).
pkg/queue/concurrency_state.go
Outdated
if err != nil { | ||
return fmt.Errorf("unable to create request: %w", err) | ||
} | ||
c.RefreshToken() |
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.
this seems like we're refreshing the token on every request rather than on a timer, but if so we don't really need the atomic, and RefreshToken doesn't need to be exported? Maybe worth converting this to something like:
ce := NewConcurrencyEndpoint(endpoint, tokenPath)
go func() {
for range time.NewTicker(1 * time.Minute).C {
ce.RefreshToken()
}
}()
(which would also let us add a test for RefreshToken, which would be nice).
pkg/queue/concurrency_state.go
Outdated
|
||
"go.uber.org/atomic" | ||
"go.uber.org/zap" | ||
) | ||
|
||
//nolint:gosec // Filepath, not hardcoded credentials | ||
const ConcurrencyStateTokenVolumeMountPath = "/var/run/secrets/tokens" | ||
const ConcurrencyStateTokenName = "state-token" | ||
const ConcurrencyStateToken = ConcurrencyStateTokenVolumeMountPath + "/" + ConcurrencyStateTokenName |
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.
bump ^
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.
/lgtm
/approve
@@ -337,6 +337,9 @@ func makeQueueContainer(rev *v1.Revision, cfg *config.Config) (*corev1.Container | |||
}, { | |||
Name: "CONCURRENCY_STATE_ENDPOINT", | |||
Value: cfg.Deployment.ConcurrencyStateEndpoint, | |||
}, { | |||
Name: "CONCURRENCY_STATE_TOKEN", | |||
Value: concurrencyStateToken, |
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.
I think I'd be tempted to do the Join here so we could drop this constant (just to avoid having 3 package-global constants for this), but maybe we can do that up in a follow-up / next time we touch this (if you agree)
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.
works for me
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: julz, psschwei 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 |
Fixes #11904
Proposed Changes
Release Note
This is part of the work to add the Pod Freezer capability to knative (see #11694 for more details)
WIP until #11802 and #11820 merge