-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
fix(credential)!: Fallback when an auth method isn't available on the current machine #13558
base: master
Are you sure you want to change the base?
Conversation
This isn't really providing much and gets in the way of tweaking the errors.
BREAKING CHANGE: `Error` because an opaque type with the enum broken out into `ErrorKind` - To construct an error from an `ErrorKind`, you can use `Into`. - To wrap an existing error, use `Error::other`
This changes cargo-credential-libsecret to report `UrlNotSupported` errors when `libsecret` can't be loaded. The goal with this change is to make it easier to support a cross-platform, cross-machine config file. Before, someone couldn't enable `libsecret` for the machines that supported it and then fallback to something else on machines that don't. After this change, we should be able to fallback to other providers. To help with debugability, we preserve the "`libsecret` can't be loaded" message by reporting the first "rich" `UrlNotSupported` error message. This is a newly invented construct as part of this PR. This was discussed on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/reg.20auth.20and.20libsecret) and in the cargo team meeting. This is to improve the cross-platform config support in an effort to deprecate having config be unset as part of rust-lang#13343
Like with `libsecret` not being present, process spawn errors can be treated as an indication that that config entry isn't relevant for the current machine and we should try other entries. If there is nothing else to fallback to, we'll still report this error.
r? @arlosi |
let mut child = cmd | ||
.spawn() | ||
.context("failed to spawn credential process") | ||
.map_err(|err| Error::from(err).with_kind(ErrorKind::UrlNotSupported))?; |
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.
Please add a comment saying why UrlNotSupported
is used here. (So that we get the behavior of attempting further providers).
@@ -72,7 +72,6 @@ os_info = "3.7.0" | |||
pasetors = { version = "0.6.8", features = ["v3", "paserk", "std", "serde"] } | |||
pathdiff = "0.2" | |||
percent-encoding = "2.3" | |||
pkg-config = "0.3.30" |
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 don't see this referenced anywhere else in the change. Is it just an unneeded dependency?
Err::<(), _>(e) | ||
.with_context(|| { | ||
format!( | ||
"credential provider `{}` could not handle the 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.
Could you please add a UI test so we can see the output when there are multiple failed providers?
}) | ||
} | ||
Err(e) => match e.kind() { | ||
cargo_credential::ErrorKind::UrlNotSupported => { |
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 sure that the UrlNotSupported
error makes sense for "non-fatal" errors. It was intended to indicate that the provider only supports some registry urls (like a provider only for a specific type of registry). It then grew to also be used for the platform-specific providers on the wrong platform - and that still made some sense since they are providers that don't work with any registry.
This use case of non-fatal (continuable) error is much further from that intent. However, I'm not sure what the right solution is.
Here are some other options:
- Make all errors "non-fatal" and continue trying providers for all error types
- Keep the existing behavior, but add an option in the global credential providers config to mark a provider as "optional"
- Add a new error type of
OtherContinuable
that that works as you've implemented it here.
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.
Talked about this in office hours
Add an alternative to Other
that is Backtrack
Backtrack
will need an MSRV note in docs- Maybe add an alias for
Other
that isCritical
- Be careful about forcing MSRV bump
As for whether every error could have a message, this was a bit unclear.
url-not-supported
: doesn't need itnot-found
: doesn't need itoperation-not-supported
: could benefit from it because a login failure on a provider that doesn't support it could give a better message saying why.
In the end, we decided that since the code was written, we should just move forward with a message on each one.
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 message printing:
- On error (everything backtracked):
- Print every provider that backtracked and the message
- On success (a provider matched)
- In extra verbose, print the providers that backtracked and the message
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.
Since we're doing a breaking change, we should also do #13615
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.
@arlosi will do that breaking change after this is merged but within the same release
@@ -177,6 +181,10 @@ available. | |||
{"Err":{ | |||
// Error: The credential could not be found in the provider. | |||
"kind":"not-found" | |||
// (Optional) Error message string to be displayed | |||
"message": "free form string error message", |
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.
Do these messages from NotFound
errors show anywhere?
☔ The latest upstream changes (presumably #13577) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (possibly 081d7ba) made this pull request unmergeable. Please resolve the merge conflicts. |
What does this PR try to resolve?
This changes cargo-credential-libsecret to report
UrlNotSupported
errors whenlibsecret
can't be loaded. This was also extended totoken-from-stdout
when the process can't be spawned.The goal with this change is to make it easier to support a
cross-platform, cross-machine config file.
Before, someone couldn't enable
libsecret
for the machines thatsupported it and then fallback to something else on machines that don't.
After this change, we should be able to fallback to other providers.
To help with debugability, we preserve the "
libsecret
can't be loaded"message by reporting the first "rich"
UrlNotSupported
error message.This is a newly invented construct as part of this PR.
This was discussed on
zulip
and in the cargo team meeting.
This is to improve the cross-platform config support in an effort to
deprecate having config be unset as part of #13343
How should we test and review this PR?
Additional information
Compatibility
cargo-credential
'sError
went from anenum
to an opaquestruct
with a separateErrorKind
cargo-credential
json messages can now contain more, optional fieldscargo-credential-libsecret
will no longer hard error iflibsecret
can't be loaded