diff options
| author | Dan Engelbrecht <[email protected]> | 2024-12-12 08:27:54 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-12-12 08:27:54 +0100 |
| commit | 9bb2bf10a76127fea1db01fab42c795bdc07c936 (patch) | |
| tree | 4bdb9d40ee265798afe4ec439dea45b7a7c5ed3c /src/zen/cmds/projectstore_cmd.cpp | |
| parent | Memory tracking improvements (#262) (diff) | |
| download | archived-zen-9bb2bf10a76127fea1db01fab42c795bdc07c936.tar.xz archived-zen-9bb2bf10a76127fea1db01fab42c795bdc07c936.zip | |
Builds API remote project store (#258)
Feature: zen command oplog-export and oplog-import now supports --builds remote target using the Jupiter builds API
Diffstat (limited to 'src/zen/cmds/projectstore_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/projectstore_cmd.cpp | 339 |
1 files changed, 266 insertions, 73 deletions
diff --git a/src/zen/cmds/projectstore_cmd.cpp b/src/zen/cmds/projectstore_cmd.cpp index 1e4f2675a..5e18a3624 100644 --- a/src/zen/cmds/projectstore_cmd.cpp +++ b/src/zen/cmds/projectstore_cmd.cpp @@ -29,7 +29,7 @@ namespace { using namespace std::literals; - const std::string DefaultCloudAccessTokenEnvVariableName( + const std::string DefaultJupiterAccessTokenEnvVariableName( #if ZEN_PLATFORM_WINDOWS "UE-CloudDataCacheAccessToken"sv #endif @@ -39,7 +39,7 @@ namespace { ); - std::string ReadCloudAccessTokenFromFile(const std::filesystem::path& Path) + std::string ReadJupiterAccessTokenFromFile(const std::filesystem::path& Path) { if (!std::filesystem::is_regular_file(Path)) { @@ -839,43 +839,66 @@ ExportOplogCommand::ExportOplogCommand() "<disable>"); m_Options.add_option("", "a", "async", "Trigger export but don't wait for completion", cxxopts::value(m_Async), "<async>"); - m_Options.add_option("", "", "cloud", "Cloud Storage URL", cxxopts::value(m_CloudUrl), "<url>"); - m_Options.add_option("cloud", "", "namespace", "Cloud Storage namespace", cxxopts::value(m_CloudNamespace), "<namespace>"); - m_Options.add_option("cloud", "", "bucket", "Cloud Storage bucket", cxxopts::value(m_CloudBucket), "<bucket>"); - m_Options.add_option("cloud", "", "key", "Cloud Storage key", cxxopts::value(m_CloudKey), "<key>"); - m_Options.add_option("cloud", + m_Options.add_option("", "", "namespace", "Cloud/Builds Storage namespace", cxxopts::value(m_JupiterNamespace), "<namespace>"); + m_Options.add_option("", "", "bucket", "Cloud/Builds Storage bucket", cxxopts::value(m_JupiterBucket), "<bucket>"); + m_Options.add_option("", "", - "basekey", - "Optional Base Cloud Storage key for incremental export", - cxxopts::value(m_BaseCloudKey), - "<key>"); + "openid-provider", + "Cloud/Builds Storage openid provider", + cxxopts::value(m_JupiterOpenIdProvider), + "<provider>"); m_Options - .add_option("cloud", "", "openid-provider", "Cloud Storage openid provider", cxxopts::value(m_CloudOpenIdProvider), "<provider>"); - m_Options.add_option("cloud", "", "access-token", "Cloud Storage access token", cxxopts::value(m_CloudAccessToken), "<accesstoken>"); - m_Options.add_option("cloud", + .add_option("", "", "access-token", "Cloud/Builds Storage access token", cxxopts::value(m_JupiterAccessToken), "<accesstoken>"); + m_Options.add_option("", "", "access-token-env", - "Name of environment variable that holds the cloud Storage access token", - cxxopts::value(m_CloudAccessTokenEnv)->default_value(DefaultCloudAccessTokenEnvVariableName), + "Name of environment variable that holds the cloud/builds Storage access token", + cxxopts::value(m_JupiterAccessTokenEnv)->default_value(DefaultJupiterAccessTokenEnvVariableName), "<envvariable>"); - m_Options.add_option("cloud", + m_Options.add_option("", "", "access-token-path", - "Path to json file that holds the cloud Storage access token", - cxxopts::value(m_CloudAccessTokenPath), + "Path to json file that holds the cloud/builds Storage access token", + cxxopts::value(m_JupiterAccessTokenPath), "<filepath>"); - m_Options.add_option("cloud", + m_Options.add_option("", "", "assume-http2", - "Assume that the cloud endpoint is a HTTP/2 endpoint skipping HTTP/1.1 upgrade handshake", - cxxopts::value(m_CloudAssumeHttp2), + "Assume that the cloud/builds endpoint is a HTTP/2 endpoint skipping HTTP/1.1 upgrade handshake", + cxxopts::value(m_JupiterAssumeHttp2), "<assumehttp2>"); + m_Options.add_option( + "", + "", + "disabletempblocks", + "Disable temp block creation and upload blocks without waiting for oplog container to be uploaded for cloud/builds storage", + cxxopts::value(m_JupiterDisableTempBlocks), + "<disable>"); + + m_Options.add_option("", "", "cloud", "Cloud Storage URL", cxxopts::value(m_CloudUrl), "<url>"); + m_Options.add_option("cloud", "", "key", "Cloud Storage key", cxxopts::value(m_CloudKey), "<key>"); m_Options.add_option("cloud", "", - "disabletempblocks", - "Disable temp block creation and upload blocks without waiting for oplog container to be uploaded", - cxxopts::value(m_CloudDisableTempBlocks), - "<disable>"); + "basekey", + "Optional Base Cloud Storage key for incremental export", + cxxopts::value(m_BaseCloudKey), + "<key>"); + + m_Options.add_option("", "", "builds", "Builds Storage API URL", cxxopts::value(m_BuildsUrl), "<url>"); + m_Options.add_option("builds", "", "builds-id", "Builds Id", cxxopts::value(m_BuildsId), "<id>"); + + m_Options.add_option("builds", + "", + "builds-metadata-path", + "Path to json file that holds the metadata for the build", + cxxopts::value(m_BuildsMetadataPath), + "<metadata-path>"); + m_Options.add_option("builds", + "", + "builds-metadata", + "Key-value pairs separated by ';' with build meta data. (key1=value1;key2=value2)", + cxxopts::value(m_BuildsMetadata), + "<metadata>"); m_Options.add_option("", "", "zen", "Zen service upload address", cxxopts::value(m_ZenUrl), "<url>"); m_Options.add_option("zen", "", "target-project", "Zen target project name", cxxopts::value(m_ZenProjectName), "<targetprojectid>"); @@ -945,6 +968,7 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg size_t TargetCount = 0; TargetCount += m_CloudUrl.empty() ? 0 : 1; + TargetCount += m_BuildsUrl.empty() ? 0 : 1; TargetCount += m_ZenUrl.empty() ? 0 : 1; TargetCount += m_FileDirectoryPath.empty() ? 0 : 1; if (TargetCount != 1) @@ -961,7 +985,7 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!m_CloudUrl.empty()) { - if (m_CloudNamespace.empty() || m_CloudBucket.empty()) + if (m_JupiterNamespace.empty() || m_JupiterBucket.empty()) { ZEN_ERROR("Options for cloud target are missing"); ZEN_CONSOLE("{}", m_Options.help({"cloud"}).c_str()); @@ -969,13 +993,40 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg } if (m_CloudKey.empty()) { - std::string KeyString = fmt::format("{}/{}/{}/{}", m_ProjectName, m_OplogName, m_CloudNamespace, m_CloudBucket); + std::string KeyString = fmt::format("{}/{}/{}/{}", m_ProjectName, m_OplogName, m_JupiterNamespace, m_JupiterBucket); IoHash Key = IoHash::HashBuffer(KeyString.data(), KeyString.size()); m_CloudKey = Key.ToHexString(); ZEN_WARN("Using auto generated cloud key '{}'", m_CloudKey); } } + if (!m_BuildsUrl.empty()) + { + if (m_JupiterNamespace.empty() || m_JupiterBucket.empty()) + { + ZEN_ERROR("Options for builds target are missing"); + ZEN_CONSOLE("{}", m_Options.help({"builds"}).c_str()); + return 1; + } + if (m_BuildsMetadataPath.empty() && m_BuildsMetadata.empty()) + { + ZEN_ERROR("Options for builds target are missing"); + ZEN_CONSOLE("{}", m_Options.help({"builds"}).c_str()); + return 1; + } + if (!m_BuildsMetadataPath.empty() && !m_BuildsMetadata.empty()) + { + ZEN_ERROR("Conflicting options for builds target"); + ZEN_CONSOLE("{}", m_Options.help({"builds"}).c_str()); + return 1; + } + if (m_BuildsId.empty()) + { + m_BuildsId = Oid::NewOid().ToString(); + ZEN_CONSOLE("Using generated builds id: {}", m_BuildsId); + } + } + if (!m_ZenUrl.empty()) { if (m_ZenProjectName.empty()) @@ -1101,32 +1152,32 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg Writer.BeginObject("cloud"sv); { Writer.AddString("url"sv, m_CloudUrl); - Writer.AddString("namespace"sv, m_CloudNamespace); - Writer.AddString("bucket"sv, m_CloudBucket); + Writer.AddString("namespace"sv, m_JupiterNamespace); + Writer.AddString("bucket"sv, m_JupiterBucket); Writer.AddString("key"sv, m_CloudKey); if (!m_BaseCloudKey.empty()) { Writer.AddString("basekey"sv, m_BaseCloudKey); } - if (!m_CloudOpenIdProvider.empty()) + if (!m_JupiterOpenIdProvider.empty()) { - Writer.AddString("openid-provider"sv, m_CloudOpenIdProvider); + Writer.AddString("openid-provider"sv, m_JupiterOpenIdProvider); } - if (!m_CloudAccessToken.empty()) + if (!m_JupiterAccessToken.empty()) { - Writer.AddString("access-token"sv, m_CloudAccessToken); + Writer.AddString("access-token"sv, m_JupiterAccessToken); } - if (!m_CloudAccessTokenPath.empty()) + if (!m_JupiterAccessTokenPath.empty()) { - std::string ResolvedCloudAccessToken = ReadCloudAccessTokenFromFile(m_CloudAccessTokenPath); + std::string ResolvedCloudAccessToken = ReadJupiterAccessTokenFromFile(m_JupiterAccessTokenPath); if (!ResolvedCloudAccessToken.empty()) { Writer.AddString("access-token"sv, ResolvedCloudAccessToken); } } - if (!m_CloudAccessTokenEnv.empty()) + if (!m_JupiterAccessTokenEnv.empty()) { - std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_CloudAccessTokenEnv); + std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_JupiterAccessTokenEnv); if (!ResolvedCloudAccessTokenEnv.empty()) { @@ -1134,10 +1185,10 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg } else { - Writer.AddString("access-token-env"sv, m_CloudAccessTokenEnv); + Writer.AddString("access-token-env"sv, m_JupiterAccessTokenEnv); } } - if (m_CloudAssumeHttp2) + if (m_JupiterAssumeHttp2) { Writer.AddBool("assumehttp2"sv, true); } @@ -1145,7 +1196,7 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg { Writer.AddBool("disableblocks"sv, true); } - if (m_CloudDisableTempBlocks) + if (m_JupiterDisableTempBlocks) { Writer.AddBool("disabletempblocks"sv, true); } @@ -1153,12 +1204,89 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg Writer.EndObject(); // "cloud" TargetDescription = fmt::format("[cloud] {}/{}/{}/{}{}{}", m_CloudUrl, - m_CloudNamespace, - m_CloudBucket, + m_JupiterNamespace, + m_JupiterBucket, m_CloudKey, m_BaseCloudKey.empty() ? "" : " Base: ", m_BaseCloudKey); } + if (!m_BuildsUrl.empty()) + { + Writer.BeginObject("builds"sv); + { + Writer.AddString("url"sv, m_BuildsUrl); + Writer.AddString("namespace"sv, m_JupiterNamespace); + Writer.AddString("bucket"sv, m_JupiterBucket); + Writer.AddString("buildsid"sv, m_BuildsId); + if (!m_JupiterOpenIdProvider.empty()) + { + Writer.AddString("openid-provider"sv, m_JupiterOpenIdProvider); + } + if (!m_JupiterAccessToken.empty()) + { + Writer.AddString("access-token"sv, m_JupiterAccessToken); + } + if (!m_JupiterAccessTokenPath.empty()) + { + std::string ResolvedCloudAccessToken = ReadJupiterAccessTokenFromFile(m_JupiterAccessTokenPath); + if (!ResolvedCloudAccessToken.empty()) + { + Writer.AddString("access-token"sv, ResolvedCloudAccessToken); + } + } + if (!m_JupiterAccessTokenEnv.empty()) + { + std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_JupiterAccessTokenEnv); + + if (!ResolvedCloudAccessTokenEnv.empty()) + { + Writer.AddString("access-token"sv, ResolvedCloudAccessTokenEnv); + } + else + { + Writer.AddString("access-token-env"sv, m_JupiterAccessTokenEnv); + } + } + if (m_JupiterAssumeHttp2) + { + Writer.AddBool("assumehttp2"sv, true); + } + if (m_DisableBlocks) + { + Writer.AddBool("disableblocks"sv, true); + } + if (m_JupiterDisableTempBlocks) + { + Writer.AddBool("disabletempblocks"sv, true); + } + + if (!m_BuildsMetadataPath.empty()) + { + std::filesystem::path MetadataPath(m_BuildsMetadataPath); + IoBuffer MetaDataJson = ReadFile(MetadataPath).Flatten(); + std::string_view Json(reinterpret_cast<const char*>(MetaDataJson.GetData()), MetaDataJson.GetSize()); + CbFieldIterator MetaData = LoadCompactBinaryFromJson(Json); + Writer.AddBinary("metadata"sv, MetaData.GetBuffer()); + } + if (!m_BuildsMetadata.empty()) + { + CbObjectWriter MetaDataWriter(m_BuildsMetadata.length()); + ForEachStrTok(m_BuildsMetadata, ';', [&](std::string_view Pair) { + size_t SplitPos = Pair.find('='); + if (SplitPos == std::string::npos || SplitPos == 0) + { + throw std::runtime_error(fmt::format("builds metadata key-value pair '{}' is malformed", Pair)); + } + MetaDataWriter.AddString(Pair.substr(0, SplitPos), Pair.substr(SplitPos + 1)); + return true; + }); + CbObject MetaData = MetaDataWriter.Save(); + Writer.AddBinary("metadata"sv, MetaData.GetBuffer()); + } + } + Writer.EndObject(); // "builds" + TargetDescription = fmt::format("[builds] {}/{}/{}/{}", m_CloudUrl, m_JupiterNamespace, m_JupiterBucket, m_BuildsId); + } if (!m_ZenUrl.empty()) { Writer.BeginObject("zen"sv); @@ -1230,32 +1358,41 @@ ImportOplogCommand::ImportOplogCommand() cxxopts::value(m_IgnoreMissingAttachments), "<ignore>"); - m_Options.add_option("", "", "cloud", "Cloud Storage URL", cxxopts::value(m_CloudUrl), "<url>"); - m_Options.add_option("cloud", "", "namespace", "Cloud Storage namespace", cxxopts::value(m_CloudNamespace), "<namespace>"); - m_Options.add_option("cloud", "", "bucket", "Cloud Storage bucket", cxxopts::value(m_CloudBucket), "<bucket>"); - m_Options.add_option("cloud", "", "key", "Cloud Storage key", cxxopts::value(m_CloudKey), "<key>"); + m_Options.add_option("", "", "namespace", "Cloud/Builds Storage namespace", cxxopts::value(m_JupiterNamespace), "<namespace>"); + m_Options.add_option("", "", "bucket", "Cloud/Builds Storage bucket", cxxopts::value(m_JupiterBucket), "<bucket>"); + m_Options.add_option("", + "", + "openid-provider", + "Cloud/Builds Storage openid provider", + cxxopts::value(m_JupiterOpenIdProvider), + "<provider>"); m_Options - .add_option("cloud", "", "openid-provider", "Cloud Storage openid provider", cxxopts::value(m_CloudOpenIdProvider), "<provider>"); - m_Options.add_option("cloud", "", "access-token", "Cloud Storage access token", cxxopts::value(m_CloudAccessToken), "<accesstoken>"); - m_Options.add_option("cloud", + .add_option("", "", "access-token", "Cloud/Builds Storage access token", cxxopts::value(m_JupiterAccessToken), "<accesstoken>"); + m_Options.add_option("", "", "access-token-env", - "Name of environment variable that holds the cloud Storage access token", - cxxopts::value(m_CloudAccessTokenEnv)->default_value(DefaultCloudAccessTokenEnvVariableName), + "Name of environment variable that holds the cloud/builds Storage access token", + cxxopts::value(m_JupiterAccessTokenEnv)->default_value(DefaultJupiterAccessTokenEnvVariableName), "<envvariable>"); - m_Options.add_option("cloud", + m_Options.add_option("", "", "access-token-path", - "Path to json file that holds the cloud Storage access token", - cxxopts::value(m_CloudAccessTokenPath), + "Path to json file that holds the cloud/builds Storage access token", + cxxopts::value(m_JupiterAccessTokenPath), "<filepath>"); - m_Options.add_option("cloud", + m_Options.add_option("", "", "assume-http2", - "Assume that the cloud endpoint is a HTTP/2 endpoint skipping HTTP/1.1 upgrade handshake", - cxxopts::value(m_CloudAssumeHttp2), + "Assume that the cloud/builds endpoint is a HTTP/2 endpoint skipping HTTP/1.1 upgrade handshake", + cxxopts::value(m_JupiterAssumeHttp2), "<assumehttp2>"); + m_Options.add_option("", "", "cloud", "Cloud Storage URL", cxxopts::value(m_CloudUrl), "<url>"); + m_Options.add_option("cloud", "", "key", "Cloud Storage key", cxxopts::value(m_CloudKey), "<key>"); + + m_Options.add_option("", "", "builds", "Builds Storage URL", cxxopts::value(m_BuildsUrl), "<url>"); + m_Options.add_option("builds", "", "builds-id", "Builds Id", cxxopts::value(m_BuildsId), "<id>"); + m_Options.add_option("", "", "zen", "Zen service upload address", cxxopts::value(m_ZenUrl), "<url>"); m_Options.add_option("zen", "", "source-project", "Zen source project name", cxxopts::value(m_ZenProjectName), "<sourceprojectid>"); m_Options.add_option("zen", "", "source-oplog", "Zen source oplog name", cxxopts::value(m_ZenOplogName), "<sourceoplogid>"); @@ -1319,6 +1456,7 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg size_t TargetCount = 0; TargetCount += m_CloudUrl.empty() ? 0 : 1; + TargetCount += m_BuildsUrl.empty() ? 0 : 1; TargetCount += m_ZenUrl.empty() ? 0 : 1; TargetCount += m_FileDirectoryPath.empty() ? 0 : 1; if (TargetCount != 1) @@ -1330,7 +1468,7 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!m_CloudUrl.empty()) { - if (m_CloudNamespace.empty() || m_CloudBucket.empty()) + if (m_JupiterNamespace.empty() || m_JupiterBucket.empty()) { ZEN_ERROR("Options for cloud source are missing"); ZEN_CONSOLE("{}", m_Options.help({"cloud"}).c_str()); @@ -1338,13 +1476,23 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg } if (m_CloudKey.empty()) { - std::string KeyString = fmt::format("{}/{}/{}/{}", m_ProjectName, m_OplogName, m_CloudNamespace, m_CloudBucket); + std::string KeyString = fmt::format("{}/{}/{}/{}", m_ProjectName, m_OplogName, m_JupiterNamespace, m_JupiterBucket); IoHash Key = IoHash::HashBuffer(KeyString.data(), KeyString.size()); m_CloudKey = Key.ToHexString(); ZEN_WARN("Using auto generated cloud key '{}'", m_CloudKey); } } + if (!m_BuildsUrl.empty()) + { + if (m_JupiterNamespace.empty() || m_JupiterBucket.empty() || m_BuildsId.empty()) + { + ZEN_ERROR("Options for builds source are missing"); + ZEN_CONSOLE("{}", m_Options.help({"builds"}).c_str()); + return 1; + } + } + if (!m_ZenUrl.empty()) { if (m_ZenProjectName.empty()) @@ -1434,28 +1582,28 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg Writer.BeginObject("cloud"sv); { Writer.AddString("url"sv, m_CloudUrl); - Writer.AddString("namespace"sv, m_CloudNamespace); - Writer.AddString("bucket"sv, m_CloudBucket); + Writer.AddString("namespace"sv, m_JupiterNamespace); + Writer.AddString("bucket"sv, m_JupiterBucket); Writer.AddString("key"sv, m_CloudKey); - if (!m_CloudOpenIdProvider.empty()) + if (!m_JupiterOpenIdProvider.empty()) { - Writer.AddString("openid-provider"sv, m_CloudOpenIdProvider); + Writer.AddString("openid-provider"sv, m_JupiterOpenIdProvider); } - if (!m_CloudAccessToken.empty()) + if (!m_JupiterAccessToken.empty()) { - Writer.AddString("access-token"sv, m_CloudAccessToken); + Writer.AddString("access-token"sv, m_JupiterAccessToken); } - if (!m_CloudAccessTokenPath.empty()) + if (!m_JupiterAccessTokenPath.empty()) { - std::string ResolvedCloudAccessToken = ReadCloudAccessTokenFromFile(m_CloudAccessTokenPath); + std::string ResolvedCloudAccessToken = ReadJupiterAccessTokenFromFile(m_JupiterAccessTokenPath); if (!ResolvedCloudAccessToken.empty()) { Writer.AddString("access-token"sv, ResolvedCloudAccessToken); } } - if (!m_CloudAccessTokenEnv.empty()) + if (!m_JupiterAccessTokenEnv.empty()) { - std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_CloudAccessTokenEnv); + std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_JupiterAccessTokenEnv); if (!ResolvedCloudAccessTokenEnv.empty()) { @@ -1463,16 +1611,61 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg } else { - Writer.AddString("access-token-env"sv, m_CloudAccessTokenEnv); + Writer.AddString("access-token-env"sv, m_JupiterAccessTokenEnv); } } - if (m_CloudAssumeHttp2) + if (m_JupiterAssumeHttp2) { Writer.AddBool("assumehttp2"sv, true); } } Writer.EndObject(); // "cloud" - SourceDescription = fmt::format("[cloud] {}/{}/{}/{}", m_CloudUrl, m_CloudNamespace, m_CloudBucket, m_CloudKey); + SourceDescription = fmt::format("[cloud] {}/{}/{}/{}", m_CloudUrl, m_JupiterNamespace, m_JupiterBucket, m_CloudKey); + } + if (!m_BuildsUrl.empty()) + { + Writer.BeginObject("builds"sv); + { + Writer.AddString("url"sv, m_BuildsUrl); + Writer.AddString("namespace"sv, m_JupiterNamespace); + Writer.AddString("bucket"sv, m_JupiterBucket); + Writer.AddString("buildsid"sv, m_BuildsId); + if (!m_JupiterOpenIdProvider.empty()) + { + Writer.AddString("openid-provider"sv, m_JupiterOpenIdProvider); + } + if (!m_JupiterAccessToken.empty()) + { + Writer.AddString("access-token"sv, m_JupiterAccessToken); + } + if (!m_JupiterAccessTokenPath.empty()) + { + std::string ResolvedCloudAccessToken = ReadJupiterAccessTokenFromFile(m_JupiterAccessTokenPath); + if (!ResolvedCloudAccessToken.empty()) + { + Writer.AddString("access-token"sv, ResolvedCloudAccessToken); + } + } + if (!m_JupiterAccessTokenEnv.empty()) + { + std::string ResolvedCloudAccessTokenEnv = GetEnvVariable(m_JupiterAccessTokenEnv); + + if (!ResolvedCloudAccessTokenEnv.empty()) + { + Writer.AddString("access-token"sv, ResolvedCloudAccessTokenEnv); + } + else + { + Writer.AddString("access-token-env"sv, m_JupiterAccessTokenEnv); + } + } + if (m_JupiterAssumeHttp2) + { + Writer.AddBool("assumehttp2"sv, true); + } + } + Writer.EndObject(); // "builds" + SourceDescription = fmt::format("[builds] {}/{}/{}/{}", m_CloudUrl, m_JupiterNamespace, m_JupiterBucket, m_BuildsId); } if (!m_ZenUrl.empty()) { |