首页
/ Moby 依赖解析:azcore(Azure SDK for Go 核心库)CHANGELOG 版本演进全解读

Moby 依赖解析:azcore(Azure SDK for Go 核心库)CHANGELOG 版本演进全解读

2026-09-06 17:37:03作者:齐冠琰

本篇技术指南以 Moby(Docker 引擎上游仓库)中 vendor 的 azcore CHANGELOG 为主体,完整梳理 Azure SDK for Go 核心库 github.com/Azure/azure-sdk-for-go/sdk/azcore 从 0.1.0(2020-01-10)到 1.21.1(2026-04-16)的全部发布历史、重大破坏性变更与关键 API 演进,并结合仓库中的 go.modvendor/modules.txt 与 vendored 源码,解释 azcore 在 Moby 依赖图中的位置及其 API 设计(Pipeline/Policy、Retry、Poller/Pager、ResponseError 等)的实现落点,帮助读者在升级或排查 Azure SDK 相关依赖时快速定位版本行为差异。

azcore 在 Moby 仓库中的位置

Moby 仓库通过 Go modules 的 vendor 机制完整纳入了 azcore。查阅 go.mod 可以看到:

github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0 // indirect

注意 // indirect 标记:Moby 自身并不直接 import azcore,它是经由 Azure 存储 SDK(azblob)等包间接引入的。vendor/modules.txt 中同样列出了 # github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 及其各子包(cloudlogpolicyruntimestreamingtotracinginternal/exportedinternal/pollers 等),与 CHANGELOG 中描述的包结构完全对应。

因此,阅读这份 CHANGELOG 的实用价值在于:当 Moby 升级 azblob/azcore 版本、或排查容器镜像分发链路中涉及 Azure Blob 存储的间接依赖行为变化时,这份发布历史是判断 API 语义、默认值与修复边界的第一手依据。

版本时间线总览

CHANGELOG 完整记录了 60+ 个版本,按阶段可归纳为:

阶段 版本区间 时间 主题
0.x 早期 0.1.0 – 0.23.1 2020-01 ~ 2022-04 基础请求/传输模型、日志、重试、LRO 轮询、分页
0.x 后期 0.23.0 – 0.23.1 2022-04 泛型化 Pager[T]/Poller[T]cloud 包、XML 修复
1.0 稳定版 1.0.0 2022-05 大规模 API 固化,多项 Breaking Changes
1.x 快速迭代 1.1.x – 1.8.0 2022-06 ~ 2023-10 重试调优、tracing、CAE、KeyCredential/SASCredential、messaging
1.x 成熟期 1.9.0 – 1.21.1 2023-11 ~ 2026-04 错误处理强化、轮询器修复、观测性增强、Go 1.23/1.25 升级

Moby 当前 vendor 的 1.21.1 属于成熟期末期版本,意味着上述所有 1.x 的修复(尤其是轮询器、重试与错误日志相关)都已包含在内。

近期版本详解(Moby 当前版本 1.21.1 及其前驱)

1.21.1 (2026-04-16):错误日志脱敏与 URL 拼接修复

这是 Moby 当前 vendor 的版本,修复点非常具体:

  1. ResponseError.Error() 中请求 URL 路径未转义的问题ResponseError 是 azcore 统一的非 2xx 响应错误类型,其定义见 errors.go
// ResponseError is returned when a request is made to a service and
// the service returns a non-success HTTP status code.
// Use errors.As() to access this type in the error chain.
//
// When marshaling instances, the RawResponse field will be omitted.
// However, the contents returned by Error() will be preserved.
type ResponseError = exported.ResponseError

注意其类型别名指向 internal/exported.ResponseError(vendored 于 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/),错误文本通过 Error() 生成时会内嵌请求 URL,1.21.1 修复了其中路径未转义、以及日志记录错误时未脱敏(redact)查询参数的问题——后者对避免凭据随查询串泄漏到日志有实际意义。

  1. runtime.JoinPaths 查询串处理修复:当 paths?(查询串)开头时,不再在 root 与 path 之间插入斜杠。该行为在当前 vendor 源码 runtime/request.go 中可以直接验证(第 74–104 行):
// JoinPaths concatenates multiple URL path segments into one path,
// inserting path separation characters as required. JoinPaths will preserve
// query parameters in the root path
func JoinPaths(root string, paths ...string) string {
	if len(paths) == 0 {
		return root
	}

	qps := ""
	if strings.Contains(root, "?") {
		splitPath := strings.Split(root, "?")
		root, qps = splitPath[0], splitPath[1]
	}
	// ...
	if strings.HasSuffix(root, "/") && strings.HasPrefix(p, "/") {
		root = root[:len(root)-1]
	} else if !strings.HasSuffix(root, "/") && !strings.HasPrefix(p, "/") && !strings.HasPrefix(p, "?") {
		p = "/" + p
	}
	// ...
}

第 102 行 !strings.HasPrefix(p, "?") 条件正是本次修复的直接落点:path 段是纯查询串时不补斜杠。该函数被 SDK 代码生成逻辑广泛使用,是排查“URL 多出一个 /”类问题的关键函数。

  1. 升级至 Go 1.25.0 并更新依赖

1.21.0 (2026-01-12):runtime/datetime 包与云受众对齐

  • 新增 runtime/datetime 包,提供专门的时间类型封装,用于按 Azure 各服务使用的多种格式(如 ISO 8601 的 date/time 变体)序列化和反序列化时间值。这是 azcore 首次把“时间编码格式”从各 SDK 自行处理收编为公共基础设施;
  • cloud.AzureGovernmentcloud.AzureChina 的 audience 值与 Azure CLI 对齐,影响多云(government/china)环境下的令牌受众断言。

1.20.0 (2025-11-06):next link 分页的动词可控

  • runtime.FetcherForNextLinkOptions 新增 HTTPVerb 字段,允许指定通过 next link 获取下一页时使用的 HTTP 动词,默认 http.MethodGet。部分 Azure 服务的分页接口要求 POST 翻页,此前无法覆盖;
  • 修复 base64 字符串解码时可能 panic 的问题;
  • 修复资源标识符(resource ID)解析对畸形 ID 不返回错误的漏洞。

1.19.x (2025-08 ~ 2025-09):ARM 资源层级解析修复

  • 1.19.1:修复 provider 专属资源层级中包含 resourceGroups 段时的资源标识符解析;改进了对不规范编写的长时运行操作(LRO)的错误回退;
  • 1.19.0:新增 runtime.APIVersionLocationPath,供把 API 版本放在 URL 路径中的客户端声明。

1.18.x (2025-04 ~ 2025-07):BearerTokenPolicy 稳健性

  • 1.18.0 新增 AccessToken.RefreshOn 字段,BearerTokenPolicy 会在决定是否申请新令牌时考虑非零值——即调用方可指定“早于过期时间多少”刷新令牌,避免临近过期窗口取令牌;
  • 1.18.2 修复 BearerTokenPolicy 未保证认证错误为不可重试(non-retriable)的情形;
  • 1.18.1 修复重试请求时 request/response 日志中 try 信息不正确,以及 ResourceID.String() 的数据竞争。

1.17.x (2025-01 ~ 2025-03)

  • 1.17.0 新增 runtime.NewPollerOptions[T]OperationLocationResultPath 字段,用于 Operation-Location 模式的 LRO 指定最终结果所在字段;arm.ResourceID 开始支持 encoding.TextMarshaler/encoding.TextUnmarshaler 接口;
  • 1.17.1 升级至 Go 1.23。

1.16.0 / 1.15.0 (2024-10):Span Kind 与 CAE 支持

  • 1.16.0:runtime.StartSpanOptions 新增 Kind 字段(创建 span 时指定 kind);修复 BearerTokenPolicy 重试前不回绕(rewind)请求体的 bug——不 rewind 会导致重试时读取到已消费的空 body;
  • 1.15.0:BearerTokenPolicy 开始处理 CAE(Continuous Access Evaluation)claims challenge——AAD 可在 200 响应中通过 WWW-Authenticate 头返回 claims,客户端需按提示重新取令牌重试;这是 Azure 平台级认证策略升级的配套能力。同时 ResponseError.RawResponse 在 JSON 序列化中被忽略(对应 1.21.1 中 errors.go 注释所述“marshaling 时 RawResponse 字段被省略”),修复了整实例无法 marshal 的问题;重试策略的整数溢出也被修复。

1.14.0 – 1.12.0 (2024):观测与工具函数

  • 1.14.0:runtime.StartSpanOptions 新增 Attributes 字段简化带属性的 span 创建;log.EventRetryPolicy 日志条目包含 HTTP 动词与 URL;
  • 1.13.0:新增 runtime.NewRequestFromRequest(),允许从既有 *http.Request 构造 policy.Request
  • 1.12.0:runtime.FetcherForNextLinkOptions 新增 StatusCodes 字段(允许把额外 HTTP 状态码视为成功);runtime 包新增 NewUUID 函数;修复 Operation-Location 策略轮询器在某些情况下无法反序列化最终结果的问题。

1.11.x (2024-04):Location 头轮询的终态判定

  • 1.11.1:使用 Location 头的轮询器不再把 http.StatusRequestTimeout(408)当作终态失败;runtime.Poller[T].Result 不再把非终态错误响应当作终态。这两项修复统一了“瞬态错误可重试”的语义;
  • 1.11.0:arm/policy.RegistrationOptions 新增 StatusCodesazcore.ClientOptions 新增 InsecureAllowCredentialWithHTTP 字段(显式允许对非 TLS 端点使用凭据,默认仍拦截);streaming 包新增 MultipartContent 类型支持自定义 Content-Type 与文件名的 multipart/form 载荷;修复 runtime.SetMultipartFormData[]byte 值的错误字符串化。

1.10.0 – 1.9.0 (2023-11 ~ 2024-02)

  • 1.10.0:新增日志事件 log.EventResponseError(创建 azcore.ResponseError 时记录其 Error() 全文);新增 runtime.NewResponseErrorWithErrorCode;新增条件请求类型 MatchConditions;修复 NullValue/IsNullValue 间竞争;runtime.EncodeQueryParams 在调用 url.ParseQuery 前转义分号(Go 的 ParseQuery; 当分隔符,见 runtime/request.gostrings.ReplaceAll(after, ";", "%3B") 的处理);
  • 1.9.2:runtime.MarshalAsByteArray/MarshalAsJSON 保留已有的 Content-Type 头;
  • 1.9.1:重试时检查 retry-after-msx-ms-retry-after-ms 头(此前漏检,导致 Azure 服务建议的精确重试间隔失效);
  • 1.9.0(重要):移除 fake 包的 NewTokenCredential(改用字面量 &fake.TokenCredential{});runtime.PipelineOptions.TracingNamespace 更名为 TracingOptions;修复一批安全与稳定性问题——非 TLS 端点阻断 Key/SAS 认证、nil 凭据不再 panic(改为跳过认证)、零值 azcore.ResponseError.Error() 不再 panic、azcore 创建的 context 值不再跨不相干的 HTTP 请求流动。

1.0 → 1.8.0:从稳定到能力爆发

1.0.0 (2022-05-12):API 固化与破坏性变更

1.0.0 是 azcore 的第一个正式稳定版,Breaking Changes 集中且影响深远,对升级代码有直接参考价值:

  • cloud.Configuration.LoginEndpoint 更名为 .ActiveDirectoryAuthorityHost
  • cloud.AzurePublicCloud 更名为 cloud.AzurePublic
  • arm/ClientOptionsarm/policy.BearerTokenOptions 移除 AuxiliaryTenants,移除 TokenRequestOptions.TenantID(跨租户认证能力推迟到后续版本以新形态回归,见 1.4.0-beta.1 与 1.6.0);
  • Poller[T].PollUntilDone() 签名变更:从 freq time.Duration 改为 options *PollUntilDoneOptions,采用统一的 options 模式;
  • 移除 arm/runtime.Poller[T]arm/runtime.NewPoller[T]()arm/runtime.NewPollerFromResumeToken[T]()arm/runtime.FinalStateVia——ARM 与 core 的轮询实现完成统一,只剩 runtime.Poller[T]
  • runtime.PageProcessor 更名 runtime.PagingHandlerNewRequestIdPolicy() 更名 NewRequestIDPolicy()
  • TokenCredential.GetToken 改为按值返回 AccessToken(而非指针),这是所有 Azure SDK 凭据实现的通用签名,1.x 时代的所有凭据库都遵循该约定;
  • 内部重构:internal/pollers/poller.go 并入 runtime/poller.goNewPipeline()ClientOptions 提供的策略置于 PipelineOptions 策略之后;默认 User-Agent 不再包含 azcore 版本号。

0.23.0 (2022-04-04):泛型与 cloud 包

  • 新增 runtime.Pager[T any]runtime.Poller[T any] 的中心化泛型实现,成为 1.x 全部分页/轮询 API 的基础形态;
  • 新增 cloud 包提供新的云配置 API,arm.Endpoint 被其取代,arm/runtime.NewPipeline()NewRPRegistrationPolicy() 开始返回 error
  • to 包改为泛型 Ptr[T]/SliceOfPtrs[T]NullValue/IsNullValue 改为泛型类型参数。

1.1.x – 1.3.x (2022-06 ~ 2023-01):重试与管道精细化

  • 1.1.3 将初始重试延迟调为 800ms(遵循 Azure SDK 指南的指数退避起点);1.1.4 增加约束:Retry-After 延迟超过 RetryOptions.MaxRetryDelay 时不再重试;runtime.JoinPaths 不再无条件在查询串前加斜杠(与 1.21.1 的修复同源,可见该函数多次被查询串边界问题驱动迭代);
  • 1.2.0 是重要能力版本:新增 ClientOptions.APIVersion(覆盖客户端默认请求的 API 版本,所有 ARM 客户端都支持);新增 tracing 包(分布式追踪的构建块)与 policy.ClientOptions.TracingProvider 字段;修复 NewPipeline 丢失管道级允许头/查询参数、MaxRetryDelay 默认值更正为 60s;
  • 1.3.0:BearerTokenOptions.AuthorizationHandler 允许向 runtime.BearerTokenPolicy 注入自定义授权逻辑;azcorearm 包新增 Client 基础类型(普通 HTTP 客户端与 ARM 客户端的最小形态);policy.Request.SetBody() 允许替换为空 body。

1.5.0 – 1.8.0 (2023-04 ~ 2023-10):跨租户、CAE 与新凭据类型

  • 1.5.0:policy.RetryOptions.ShouldRetry 提供细粒度重试判定钩子;同时把 TokenRequestOptions.Claims/TenantID 从正式版移除(beta 特性回归 1.6.0 线);
  • 1.6.0:ARM 跨租户认证落地——设置 arm.ClientOptions.AuxiliaryTenants 启用;policy.TokenRequestOptions 新增 TenantID
  • 1.7.0:azcore.Client 新增 WithClientName() 支持以新名称浅克隆客户端用于 tracing;1.7.1 在默认传输策略启用 TLS 重新协商;1.7.2 修复默认 HTTP 传输在 WASM 环境下的工作问题;
  • 1.8.0 能力集中爆发(含 1.8.0-beta.N 的累积特性):
    • Claims 与 CAE 认证正式进入正式版本;
    • 新增 messaging 包:messaging.CloudEvent 支持按 CloudEvents 1.0 规范序列化/反序列化(beta.1 引入,beta.2 中 Data 的 JSON 对象由 json.RawMessage 改为 []byte 反序列化);
    • 新增 azcore 包的 KeyCredential/SASCredential 类型及 runtime 包的 KeyCredentialPolicy/SASCredentialPolicy(含构造函数与 options 类型)——补齐 Bearer 之外的密钥类认证;
    • 非 TLS 端点阻断 Bearer 认证(安全加固);
    • 1.8.0-beta.3:runtime.FetcherForNextLink/FetcherForNextLinkOptions 将“从 next link URL 创建 Pager[T].Fetcher”逻辑集中化;WithCaptureResponseWithHTTPHeaderWithRetryOptionsruntime 迁移到 policy 包导出并弃用旧版;
    • 1.8.0-beta.2:server 包新增 SanitizePagerPollerPathTokenRequestOptions.EnableCAE 指示是否请求 CAE 令牌。

0.x 基础阶段:请求-传输模型与重试的成型(0.1.0 – 0.22.0)

早期 0.x 版本建立了 azcore 至今未变的骨架,理解这些决定有助于读懂 1.x 的 API 形态:

  • 0.10.0 (2020-09-10) 是模型定型点requesttransport 接口重构为与标准库对齐的模式;NewRequest() 改用 http.NewRequestWithContext() 并新增 context 参数;PolicyTransport 接口移除 context 参数(context 挂在底层 http.Request 上);Pipeline.Do() 在发送前校验请求,避免对畸形请求做无谓重试;Retrier 接口被 NonRetriableError 取代;Request.SetBody() 要求传入 content type;路径拼接收拢到 JoinPaths()。这一版确立的“策略管道 + 不可变请求”模型就是今天 policy.ClientOptions/runtime.Pipeline 的雏形;
  • 重试语义逐步打磨:0.4.0 支持每次调用通过 WithRetryOptions() 传入自定义重试选项、从默认重试状态码中移除 429、MaxTries 更名 MaxRetries;0.9.4 明确 per-try 超时的取消时机(HTTP 请求返回即取消,而非 body 读完)、body 下载失败时不重试非幂等操作;
  • 日志体系:0.10.1 提供默认 console logger(写 stderr,通过环境变量 AZURE_SDK_GO_LOGGING=all 启用);0.18.0 把 Logger 类型改为包级方法 azcore.SetClassifications/azcore.SetListener;0.21.0 为 policy.LogOptions 增加 AllowedHeaders/AllowedQueryParams 白名单,并引入 azcore.ResponseError 类型(非 2xx 时由 API 返回的统一错误类型,即 1.21.1 修复的 Error() 脱敏对象);
  • 认证演进:0.17.0 引入 TokenRequestOptions.TenantIDAuthenticationOptions.AuxiliaryTenants;0.20.0 移除 azcore.Credential/NewAnonymousCredential()NewRPRegistrationPolicy 直接要求 azcore.TokenCredentialruntime.NewPipeline 新签名简化自定义认证实现;
  • LRO 与分页:0.14.4 提供基础 LRO 轮询(LROPoller);0.14.3 支持 multipart 表单数据(Request.WriteMultipartFormData());0.19.0 把 LRO 轮询逻辑在 ARM 与 core 实现间统一;0.22.0 引入 runtime.WithCaptureResponse(默认关闭,启用后 API 调用可取回原始 HTTP 响应);
  • JSON 编码细节:0.14.2 的 NullValue()/IsNullValue() 哨兵值机制、0.15.0 导出 Response.Payload()、0.16.0 修复 UnmarshalAsByteArray()、0.9.2 的 azure:"ro" 只读字段注解(请求载荷中自动剔除只读字段并做对象图深拷贝)——这些至今仍是 runtime.MarshalAsJSON 的行为基础。

关键设计决策的源码印证

结合 vendor 源码可以验证 CHANGELOG 中几项描述的落点:

  1. 包结构与 0.19.0 的拆分一致vendor 目录 顶层有 cloudlogpolicyruntimestreamingtotracing 七个子包加根包(core.goerrors.goetag.godoc.go),正是 0.19.0 changelog 所述“按使用场景拆分内容”(核心/通用/SDK 作者)的最终形态;
  2. 错误类型的别名模式ResponseError = exported.ResponseError(见 errors.go)表明对外类型由 internal/exported 维护、对外导出别名——这类内部实现细节(如 1.21.1 的 URL 转义与查询参数脱敏修复)都在 internal 包中完成,而对外契约保持别名稳定;
  3. 查询串边界问题反复出现:从 0.18.1(JoinPaths 保留 root 中已编码的查询参数)、1.1.4(不无条件在查询串前加斜杠)到 1.21.1(paths 以 ? 开头时不补斜杠),runtime/request.goJoinPaths? 的三段式处理(root 拆分、path 拼接、条件补斜杠)是这条修复链的累积结果;
  4. 1.10.0 的分号转义修复同样可在源码中直接看到:url.ParseQuery(strings.ReplaceAll(after, ";", "%3B")),源码注释还引用了 Go 标准库 issue 说明 ; 分隔符背景。

升级与排查建议

基于 Moby 当前 vendor 的 1.21.1 与 CHANGELOG 的完整历史,给出几条可操作的结论:

  • 对齐凭据签名:任何自实现 azcore.TokenCredential 的代码必须按 1.0.0 后的签名按值返回 AccessToken;若还要响应 CAE(1.15.0 起 azcore 自动处理 challenge),令牌提供方需支持 claims 参数;
  • 分页/轮询行为:1.11.1 之后,基于 Location/Operation-Location 头的轮询器对 408/429 等瞬态状态不再误判终态;1.20.0 起翻页动词可通过 HTTPVerb 覆盖;如果业务代码自己实现了 next-link 翻页,建议对齐 FetcherForNextLink 的集中化实现(1.8.0-beta.3 引入);
  • 日志安全:1.21.1 的错误日志已转义 URL 并脱敏查询参数,若依赖旧版本自建日志管道,应注意 ResponseError 文本可能含未脱敏查询串;
  • 版本升级路径:从 0.x 直升 1.x 必须处理 1.0.0 的 Breaking Changes 清单(PollUntilDone 签名、cloud.AzurePublic 更名、ARM poller 统一等);1.9.0/1.8.0 的 beta 特性开关(CAE、tracing、fakes 在不同 beta 间反复增删)说明跨 beta 迁移时需对照具体小版本的 Breaking Changes 段落。

小结

这份 vendored CHANGELOG 完整呈现了 azcore 从 0.1.0 的请求模型原型到 1.21.1 的成熟形态:以 0.10.0 定型策略管道、0.23.0 完成泛型化、1.0.0 固化 API、1.6.0–1.15.0 补齐跨租户/CAE/CAE-challenge 等认证能力、1.9.x–1.21.x 持续强化轮询器、重试与错误日志的稳健性。对 Moby 而言,azcore 作为 azblob 的间接依赖被 vendor 固定在 1.21.1,理解其版本历史可以在依赖升级、Azure 存储链路排障与错误日志审计时给出精确的行为边界判断。

登录后查看全文
热门项目推荐
相关项目推荐