mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 12:06:01 +01:00
Merge branch 'master' into eval-copy-less
This commit is contained in:
commit
d2c0c0607c
3 changed files with 72 additions and 42 deletions
|
|
@ -508,8 +508,15 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lookupPath Only used during construction.
|
||||||
|
* @param store The store to use for instantiation
|
||||||
|
* @param fetchSettings Must outlive the lifetime of this EvalState!
|
||||||
|
* @param settings Must outlive the lifetime of this EvalState!
|
||||||
|
* @param buildStore The store to use for builds ("import from derivation", C API `nix_string_realise`)
|
||||||
|
*/
|
||||||
EvalState(
|
EvalState(
|
||||||
const LookupPath & _lookupPath,
|
const LookupPath & lookupPath,
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
const fetchers::Settings & fetchSettings,
|
const fetchers::Settings & fetchSettings,
|
||||||
const EvalSettings & settings,
|
const EvalSettings & settings,
|
||||||
|
|
|
||||||
|
|
@ -118,48 +118,57 @@ AwsCredentials getAwsCredentials(const std::string & profile)
|
||||||
// Get or create credential provider with caching
|
// Get or create credential provider with caching
|
||||||
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> provider;
|
std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> provider;
|
||||||
|
|
||||||
// Try to find existing provider
|
// Use try_emplace_and_cvisit for atomic get-or-create
|
||||||
credentialProviderCache.visit(profile, [&](const auto & pair) { provider = pair.second; });
|
// This prevents race conditions where multiple threads create providers
|
||||||
|
credentialProviderCache.try_emplace_and_cvisit(
|
||||||
|
profile,
|
||||||
|
nullptr, // Placeholder - will be replaced in f1 before any thread can see it
|
||||||
|
[&](auto & kv) {
|
||||||
|
// f1: Called atomically during insertion with non-const reference
|
||||||
|
// Other threads are blocked until we finish, so nullptr is never visible
|
||||||
|
debug(
|
||||||
|
"[pid=%d] creating new AWS credential provider for profile '%s'",
|
||||||
|
getpid(),
|
||||||
|
profile.empty() ? "(default)" : profile.c_str());
|
||||||
|
|
||||||
if (!provider) {
|
try {
|
||||||
// Create new provider if not found
|
initAwsCrt();
|
||||||
debug(
|
|
||||||
"[pid=%d] creating new AWS credential provider for profile '%s'",
|
|
||||||
getpid(),
|
|
||||||
profile.empty() ? "(default)" : profile.c_str());
|
|
||||||
|
|
||||||
try {
|
if (profile.empty()) {
|
||||||
initAwsCrt();
|
Aws::Crt::Auth::CredentialsProviderChainDefaultConfig config;
|
||||||
|
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
|
||||||
|
kv.second = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderChainDefault(config);
|
||||||
|
} else {
|
||||||
|
Aws::Crt::Auth::CredentialsProviderProfileConfig config;
|
||||||
|
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
|
||||||
|
// This is safe because the underlying C library will copy this string
|
||||||
|
// c.f. https://github.com/awslabs/aws-c-auth/blob/main/source/credentials_provider_profile.c#L220
|
||||||
|
config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profile.c_str());
|
||||||
|
kv.second = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config);
|
||||||
|
}
|
||||||
|
|
||||||
if (profile.empty()) {
|
if (!kv.second) {
|
||||||
Aws::Crt::Auth::CredentialsProviderChainDefaultConfig config;
|
throw AwsAuthError(
|
||||||
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
|
"Failed to create AWS credentials provider for %s",
|
||||||
provider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderChainDefault(config);
|
profile.empty() ? "default profile" : fmt("profile '%s'", profile));
|
||||||
} else {
|
}
|
||||||
Aws::Crt::Auth::CredentialsProviderProfileConfig config;
|
|
||||||
config.Bootstrap = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultClientBootstrap();
|
provider = kv.second;
|
||||||
// This is safe because the underlying C library will copy this string
|
} catch (Error & e) {
|
||||||
// c.f. https://github.com/awslabs/aws-c-auth/blob/main/source/credentials_provider_profile.c#L220
|
// Exception during creation - remove the entry to allow retry
|
||||||
config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profile.c_str());
|
credentialProviderCache.erase(profile);
|
||||||
provider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config);
|
e.addTrace({}, "for AWS profile: %s", profile.empty() ? "(default)" : profile);
|
||||||
|
throw;
|
||||||
|
} catch (...) {
|
||||||
|
// Non-Error exception - still need to clean up
|
||||||
|
credentialProviderCache.erase(profile);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
} catch (Error & e) {
|
},
|
||||||
e.addTrace(
|
[&](const auto & kv) {
|
||||||
{},
|
// f2: Called if key already exists (const reference)
|
||||||
"while creating AWS credentials provider for %s",
|
provider = kv.second;
|
||||||
profile.empty() ? "default profile" : fmt("profile '%s'", profile));
|
});
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!provider) {
|
|
||||||
throw AwsAuthError(
|
|
||||||
"Failed to create AWS credentials provider for %s",
|
|
||||||
profile.empty() ? "default profile" : fmt("profile '%s'", profile));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert into cache (try_emplace is thread-safe and won't overwrite if another thread added it)
|
|
||||||
credentialProviderCache.try_emplace(profile, provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getCredentialsFromProvider(provider);
|
return getCredentialsFromProvider(provider);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,13 +192,27 @@ public:
|
||||||
err.traces.push_front(trace);
|
err.traces.push_front(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepends an item to the error trace, as is usual for extra context.
|
||||||
|
*
|
||||||
|
* @param pos Nullable source position to put in trace item
|
||||||
|
* @param fs Format string, see `HintFmt`
|
||||||
|
* @param args... Format string arguments.
|
||||||
|
*/
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
void addTrace(std::shared_ptr<const Pos> && e, std::string_view fs, const Args &... args)
|
void addTrace(std::shared_ptr<const Pos> && pos, std::string_view fs, const Args &... args)
|
||||||
{
|
{
|
||||||
addTrace(std::move(e), HintFmt(std::string(fs), args...));
|
addTrace(std::move(pos), HintFmt(std::string(fs), args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTrace(std::shared_ptr<const Pos> && e, HintFmt hint, TracePrint print = TracePrint::Default);
|
/**
|
||||||
|
* Prepends an item to the error trace, as is usual for extra context.
|
||||||
|
*
|
||||||
|
* @param pos Nullable source position to put in trace item
|
||||||
|
* @param hint Formatted error message
|
||||||
|
* @param print Optional, whether to always print (used by `addErrorContext`)
|
||||||
|
*/
|
||||||
|
void addTrace(std::shared_ptr<const Pos> && pos, HintFmt hint, TracePrint print = TracePrint::Default);
|
||||||
|
|
||||||
bool hasTrace() const
|
bool hasTrace() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue