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

oauth/api: drain timer channel on each iteration #5376

Merged
merged 1 commit into from
Sep 3, 2024

Conversation

laurazard
Copy link
Member

Fixes #5375

- What I did

Previously, if while polling for oauth device-code login results a user suspended the process (such as with CTRL-Z) and then restored it with fg, an error might occur in the form of:

failed waiting for authentication: You are polling faster than the specified interval of 5 seconds.

This is due to our use of a time.Ticker here - if no receiver drains the ticker channel (and timers/tickers use a buffered channel behind the scenes), more than one tick will pile up, causing the program to "tick" twice, in fast succession, after it is resumed.

- How I did it

The new implementation replaces the time.Ticker with a time.Timer (time.Ticker is just a nice wrapper) and introduces a helper function resetTimer to ensure that before every select, the timer is stopped and it's channel is drained.

- How to verify it

Reproduce as described in #5375

- Description for the changelog

Fix issue that will sometimes cause the browser-login flow to fail if the CLI process is suspended and then resumed while waiting for the user to authenticate.

- A picture of a cute animal (not mandatory but encouraged)

@laurazard laurazard self-assigned this Aug 28, 2024
@codecov-commenter
Copy link

codecov-commenter commented Aug 28, 2024

Codecov Report

Attention: Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.

Project coverage is 60.97%. Comparing base (3826f5a) to head (60d0450).
Report is 13 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5376      +/-   ##
==========================================
+ Coverage   60.93%   60.97%   +0.03%     
==========================================
  Files         304      304              
  Lines       21348    21358      +10     
==========================================
+ Hits        13009    13022      +13     
+ Misses       7409     7407       -2     
+ Partials      930      929       -1     

Copy link
Contributor

@dvdksn dvdksn left a comment

Choose a reason for hiding this comment

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

works in my local test 🎉

@laurazard
Copy link
Member Author

@thaJeztah @vvoland PTAL

@laurazard laurazard force-pushed the fix-oauth-login-timer branch 2 times, most recently from 614fb9c to ad483cf Compare September 2, 2024 14:43
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Thanks for updating! Left two comments 🙈

res, err := a.getDeviceToken(ctx, state)
if err != nil {
if errors.Is(err, context.Canceled) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to handle context.DeadlineExceeded here? We could even use the errdefs helper, but not sure if we want to import it here;

// IsContext returns if the passed in error is due to context cancellation or deadline exceeded.
func IsContext(err error) bool {
return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, the purpose of that:

// if the caller canceled the context, continue
// and let the select hit the ctx.Done() branch

is just to make sure we hit the user canceled login error if the user cancels execution while API.getDeviceToken is going rather than the context canceled error from there, so I don't think we need it. This is also all inside /internal, so we don't expect others to import this, so I think it's fine. If the user does get a timeout while trying to connect to the tenant, I think we should error out and let them know.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, right; yeah, was curious if we wanted to retry if the connection timed out. I guess that would be a bit of an exceptional case, so returning early in that case makes sense as well.

Thanks!

cli/internal/oauth/api/api.go Outdated Show resolved Hide resolved
Previously, if while polling for oauth device-code login results a user
suspended the process (such as with CTRL-Z) and then restored it with
`fg`, an error might occur in the form of:

```
failed waiting for authentication: You are polling faster than the specified interval of 5 seconds.
```

This is due to our use of a `time.Ticker` here - if no receiver drains
the ticker channel (and timers/tickers use a buffered channel behind the
scenes), more than one tick will pile up, causing the program to "tick"
twice, in fast succession, after it is resumed.

The new implementation replaces the `time.Ticker` with a `time.Timer`
(`time.Ticker` is just a nice wrapper) and introduces a helper function
`resetTimer` to ensure that before every `select`, the timer is stopped
and it's channel is drained.

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

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@thaJeztah thaJeztah merged commit 51f320f into docker:master Sep 3, 2024
89 checks passed
renovate bot added a commit to earthly/dind that referenced this pull request Sep 9, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [docker/docker](https://redirect.github.com/docker/docker) | patch |
`27.2.0` -> `27.2.1` |

---

### Release Notes

<details>
<summary>docker/docker (docker/docker)</summary>

###
[`v27.2.1`](https://redirect.github.com/moby/moby/releases/tag/v27.2.1)

[Compare
Source](https://redirect.github.com/docker/docker/compare/v27.2.0-rc.1...v27.2.1)

#### 27.2.1

For a full list of pull requests and changes in this release, refer to
the relevant GitHub milestones:

- [docker/cli, 27.2.1
milestone](https://redirect.github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A27.2.1)
- [moby/moby, 27.2.1
milestone](https://redirect.github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A27.2.1)

##### Bug fixes and enhancements

- containerd image store: Fix non-container images being hidden in the
`docker images` output.
[moby/moby#48402](https://redirect.github.com/moby/moby/pull/48402)
- containerd image store: Improve `docker pull` error message when the
image platform doesn't match.
[moby/moby#48415](https://redirect.github.com/moby/moby/pull/48415)
- CLI: Fix issue causing login to not remove repository names from
passed in registry addresses, resulting in credentials being stored
under the wrong key.
[docker/cli#5385](https://redirect.github.com/docker/cli/pull/5385)
- CLI: Fix issue that will sometimes cause the browser-login flow to
fail if the CLI process is suspended and then resumed while waiting for
the user to authenticate.
[docker/cli#5376](https://redirect.github.com/docker/cli/pull/5376)
- CLI: `docker login` now returns an error instead of hanging if called
non-interactively with `--password` or `--password-stdin` but without
`--user`.
[docker/cli#5402](https://redirect.github.com/docker/cli/pull/5402)

##### Packaging updates

- Update `runc` to
[v1.1.14](https://redirect.github.com/opencontainers/runc/releases/tag/v1.1.14),
which contains a fix for
[CVE-2024-45310](https://redirect.github.com/opencontainers/runc/security/advisories/GHSA-jfvp-7x6p-h2pv).
[moby/moby#48426](https://redirect.github.com/moby/moby/pull/48426)
- Update Go runtime to 1.22.7.
[moby/moby#48433](https://redirect.github.com/moby/moby/pull/48433),
[docker/cli#5411](https://redirect.github.com/docker/cli/pull/5411),
[docker/docker-ce-packaging#1068](https://redirect.github.com/docker/docker-ce-packaging/pull/1068)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 6am on monday" (UTC), Automerge
- At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/earthly/dind).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC41OS4yIiwidXBkYXRlZEluVmVyIjoiMzguNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsicmVub3ZhdGUiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot added a commit to earthly/dind that referenced this pull request Sep 9, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [docker/docker](https://redirect.github.com/docker/docker) | patch |
`27.2.0` -> `27.2.1` |

---

### Release Notes

<details>
<summary>docker/docker (docker/docker)</summary>

###
[`v27.2.1`](https://redirect.github.com/moby/moby/releases/tag/v27.2.1)

[Compare
Source](https://redirect.github.com/docker/docker/compare/v27.2.0-rc.1...v27.2.1)

#### 27.2.1

For a full list of pull requests and changes in this release, refer to
the relevant GitHub milestones:

- [docker/cli, 27.2.1
milestone](https://redirect.github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A27.2.1)
- [moby/moby, 27.2.1
milestone](https://redirect.github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A27.2.1)

##### Bug fixes and enhancements

- containerd image store: Fix non-container images being hidden in the
`docker image ls` output.
[moby/moby#48402](https://redirect.github.com/moby/moby/pull/48402)
- containerd image store: Improve `docker pull` error message when the
image platform doesn't match.
[moby/moby#48415](https://redirect.github.com/moby/moby/pull/48415)
- CLI: Fix issue causing `docker login` to not remove repository names
from passed in registry addresses, resulting in credentials being stored
under the wrong key.
[docker/cli#5385](https://redirect.github.com/docker/cli/pull/5385)
- CLI: Fix issue that will sometimes cause the browser-login flow to
fail if the CLI process is suspended and then resumed while waiting for
the user to authenticate.
[docker/cli#5376](https://redirect.github.com/docker/cli/pull/5376)
- CLI: `docker login` now returns an error instead of hanging if called
non-interactively with `--password` or `--password-stdin` but without
`--user`.
[docker/cli#5402](https://redirect.github.com/docker/cli/pull/5402)

##### Packaging updates

- Update `runc` to
[v1.1.14](https://redirect.github.com/opencontainers/runc/releases/tag/v1.1.14),
which contains a fix for
[CVE-2024-45310](https://redirect.github.com/opencontainers/runc/security/advisories/GHSA-jfvp-7x6p-h2pv).
[moby/moby#48426](https://redirect.github.com/moby/moby/pull/48426)
- Update Go runtime to 1.22.7.
[moby/moby#48433](https://redirect.github.com/moby/moby/pull/48433),
[docker/cli#5411](https://redirect.github.com/docker/cli/pull/5411),
[docker/docker-ce-packaging#1068](https://redirect.github.com/docker/docker-ce-packaging/pull/1068)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 6am on monday" (UTC), Automerge
- At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/earthly/dind).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC41OS4yIiwidXBkYXRlZEluVmVyIjoiMzguNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsicmVub3ZhdGUiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@laurazard laurazard added this to the 27.2.1 milestone Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suspending docker login causes an error
5 participants