instance-repo 1.3.0.dev0__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/PKG-INFO +7 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/README.md +6 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/__init__.py +1 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/bootstrap.py +2 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/config.py +37 -3
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/images.py +1 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/instances.py +4 -2
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/versions.py +4 -4
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/repo.py +5 -3
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/store/acr.py +32 -17
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/PKG-INFO +7 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/pyproject.toml +1 -1
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/_routing.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/_site_defaults.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/artifacts.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/cache.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/cli.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/__init__.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/benchmarks.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/datasets.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/reports.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/scaffold.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/splits.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/clients/workflows.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/concurrency.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/content.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/endpoints.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/errors.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/image.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/layout.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/loader.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/models.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/paths.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/release.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/retry.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/store/__init__.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/store/base.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/store/oss.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/store/registry.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/tasktoml.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/transport.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo/validate.py +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/SOURCES.txt +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/dependency_links.txt +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/entry_points.txt +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/requires.txt +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/top_level.txt +0 -0
- {instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: instance-repo
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: InstanceRepo SDK — 评测 Instance 统一存储客户端(SDK-only;控制面由 apiserver 承载)
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -58,6 +58,12 @@ pip install "instance-repo[oss]" # 需要数据面 OSS 读写时,附带 os
|
|
|
58
58
|
`profile_overrides={"acr_namespace": ...}`;默认 namespace 由 repo-config 返回,但**必须由部署方
|
|
59
59
|
在 ACR 企业版实例中预建**,SDK 不会创建)。
|
|
60
60
|
|
|
61
|
+
**公网 ACR registry(runner 不在 VPC 内网时)**:默认使用 repo-config 返回的 `registry`
|
|
62
|
+
(VPC 内网域名)。runner 不在对应 VPC 内时,设环境变量 `IR_ACR_PREFER_PUBLIC=1`(或
|
|
63
|
+
`Repo(profile_overrides={"prefer_public_registry": True})`),SDK 会改走 `public_registry`
|
|
64
|
+
(公网域名);公网值缺失时静默回落到 VPC 值。也可用 `IR_ACR_PUBLIC_HOST` /
|
|
65
|
+
`profile_overrides={"acr_public_host": ...}` 显式指定公网 registry。
|
|
66
|
+
|
|
61
67
|
兼容别名表:
|
|
62
68
|
|
|
63
69
|
| 旧名 | 新名或状态 | 优先级 | 告警 |
|
|
@@ -44,6 +44,12 @@ pip install "instance-repo[oss]" # 需要数据面 OSS 读写时,附带 os
|
|
|
44
44
|
`profile_overrides={"acr_namespace": ...}`;默认 namespace 由 repo-config 返回,但**必须由部署方
|
|
45
45
|
在 ACR 企业版实例中预建**,SDK 不会创建)。
|
|
46
46
|
|
|
47
|
+
**公网 ACR registry(runner 不在 VPC 内网时)**:默认使用 repo-config 返回的 `registry`
|
|
48
|
+
(VPC 内网域名)。runner 不在对应 VPC 内时,设环境变量 `IR_ACR_PREFER_PUBLIC=1`(或
|
|
49
|
+
`Repo(profile_overrides={"prefer_public_registry": True})`),SDK 会改走 `public_registry`
|
|
50
|
+
(公网域名);公网值缺失时静默回落到 VPC 值。也可用 `IR_ACR_PUBLIC_HOST` /
|
|
51
|
+
`profile_overrides={"acr_public_host": ...}` 显式指定公网 registry。
|
|
52
|
+
|
|
47
53
|
兼容别名表:
|
|
48
54
|
|
|
49
55
|
| 旧名 | 新名或状态 | 优先级 | 告警 |
|
|
@@ -36,7 +36,8 @@ _logger = logging.getLogger(__name__)
|
|
|
36
36
|
DISCOVERY_TTL_SECONDS = 3600.0
|
|
37
37
|
|
|
38
38
|
#: 由自动发现填充的字段(scaffold 两项不在 repo-config 返回范围内,仍须显式提供)。
|
|
39
|
-
DISCOVERABLE_FIELDS = ("oss_bucket", "oss_prefix", "acr_host",
|
|
39
|
+
DISCOVERABLE_FIELDS = ("oss_bucket", "oss_prefix", "acr_host",
|
|
40
|
+
"acr_public_host", "acr_namespace")
|
|
40
41
|
|
|
41
42
|
_cache = TTLCache(safety=0.0)
|
|
42
43
|
_lock = threading.Lock()
|
|
@@ -76,6 +76,11 @@ ENV_OSS_PREFIX = "IR_OSS_PREFIX"
|
|
|
76
76
|
ENV_SCAFFOLD_BUCKET = "IR_SCAFFOLD_BUCKET"
|
|
77
77
|
ENV_SCAFFOLD_ROOT = "IR_SCAFFOLD_ROOT"
|
|
78
78
|
|
|
79
|
+
# 公网 ACR registry:runner 不在 VPC 内网时,可显式切换使用公网 registry。
|
|
80
|
+
ENV_ACR_PUBLIC_HOST = "IR_ACR_PUBLIC_HOST"
|
|
81
|
+
# 是否优先使用公网 registry("1"/"true"/"on",大小写不敏感)。
|
|
82
|
+
ENV_ACR_PREFER_PUBLIC = "IR_ACR_PREFER_PUBLIC"
|
|
83
|
+
|
|
79
84
|
#: v0.8 弃用的手工寻址环境变量 → 建议替代。scaffold 两项不在其中:scaffold 包不在
|
|
80
85
|
#: repo-config 的返回范围内,仍须显式提供。
|
|
81
86
|
DEPRECATED_ADDRESS_ENVS = {
|
|
@@ -179,6 +184,7 @@ class Profile:
|
|
|
179
184
|
name: str
|
|
180
185
|
oss_bucket: str = ""
|
|
181
186
|
acr_host: str = ""
|
|
187
|
+
acr_public_host: str = ""
|
|
182
188
|
acr_namespace: str = ""
|
|
183
189
|
oss_prefix: str = DEFAULT_OSS_PREFIX
|
|
184
190
|
scaffold_bucket: str = ""
|
|
@@ -197,6 +203,21 @@ class Profile:
|
|
|
197
203
|
#: ``bootstrap.discover()`` 捕获异常时写入;``require()`` 据此在报错消息里
|
|
198
204
|
#: 透传根因,避免"返回里没有 acr_host"这类误导性口径。
|
|
199
205
|
discovery_error: str = ""
|
|
206
|
+
#: 优先使用公网 ACR registry(默认 False=走 VPC 内网)。runner 不在 VPC
|
|
207
|
+
#: 内网时置 True,配合 ``acr_public_host``(repo-config 的 public_registry)
|
|
208
|
+
#: 生效;公网值缺失时静默回落到 ``acr_host``。
|
|
209
|
+
prefer_public_registry: bool = False
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def effective_acr_host(self) -> str:
|
|
213
|
+
"""ACR 操作实际使用的 registry host。
|
|
214
|
+
|
|
215
|
+
默认返回 ``acr_host``(repo-config 的 registry,通常是 VPC 内网域名);
|
|
216
|
+
``prefer_public_registry=True`` 且 ``acr_public_host`` 非空时返回公网域名。
|
|
217
|
+
"""
|
|
218
|
+
if self.prefer_public_registry and self.acr_public_host:
|
|
219
|
+
return self.acr_public_host
|
|
220
|
+
return self.acr_host
|
|
200
221
|
|
|
201
222
|
@property
|
|
202
223
|
def dataset_environment(self) -> str:
|
|
@@ -240,12 +261,14 @@ def load_profile(name: str = "default", *, overrides: dict | None = None,
|
|
|
240
261
|
storage_env, ENV_STORAGE_ENV, LEGACY_ENV_STORAGE_ENV)
|
|
241
262
|
env_values = {k: os.environ.get(k, "") for k in
|
|
242
263
|
(ENV_OSS_BUCKET, ENV_ACR_HOST, ENV_ACR_NAMESPACE,
|
|
264
|
+
ENV_ACR_PUBLIC_HOST,
|
|
243
265
|
ENV_OSS_PREFIX, ENV_SCAFFOLD_BUCKET, ENV_SCAFFOLD_ROOT)}
|
|
244
266
|
_warn_deprecated_envs(env_values)
|
|
245
267
|
cfg = {
|
|
246
268
|
"oss_bucket": env_values[ENV_OSS_BUCKET],
|
|
247
269
|
"acr_host": env_values[ENV_ACR_HOST],
|
|
248
270
|
"acr_namespace": env_values[ENV_ACR_NAMESPACE],
|
|
271
|
+
"acr_public_host": env_values[ENV_ACR_PUBLIC_HOST],
|
|
249
272
|
"oss_prefix": env_values[ENV_OSS_PREFIX] or DEFAULT_OSS_PREFIX,
|
|
250
273
|
"scaffold_bucket": env_values[ENV_SCAFFOLD_BUCKET],
|
|
251
274
|
"scaffold_root": env_values[ENV_SCAFFOLD_ROOT],
|
|
@@ -259,19 +282,28 @@ def load_profile(name: str = "default", *, overrides: dict | None = None,
|
|
|
259
282
|
sources["api_env"] = "env"
|
|
260
283
|
else:
|
|
261
284
|
sources["api_env"] = ""
|
|
285
|
+
prefer_public = False
|
|
262
286
|
if overrides:
|
|
263
|
-
# 只接受已知字段,避免把 api_env
|
|
264
|
-
|
|
265
|
-
|
|
287
|
+
# 只接受已知字段,避免把 api_env 之类误当数据面字段;
|
|
288
|
+
# prefer_public_registry 单独取(非寻址字段,不进 **cfg 传 Profile)。
|
|
289
|
+
for k in ("oss_bucket", "acr_host", "acr_namespace", "acr_public_host",
|
|
290
|
+
"oss_prefix", "scaffold_bucket", "scaffold_root", "api_base"):
|
|
266
291
|
if k in overrides and overrides[k] is not None:
|
|
267
292
|
cfg[k] = overrides[k]
|
|
268
293
|
sources[k] = "explicit"
|
|
294
|
+
if overrides.get("prefer_public_registry") is not None:
|
|
295
|
+
prefer_public = bool(overrides["prefer_public_registry"])
|
|
269
296
|
if cfg["api_base"]:
|
|
270
297
|
cfg["api_base"] = str(cfg["api_base"]).rstrip("/")
|
|
298
|
+
if not prefer_public:
|
|
299
|
+
# 环境变量开关:IR_ACR_PREFER_PUBLIC=1/true/on(大小写不敏感)
|
|
300
|
+
prefer_public = os.environ.get(ENV_ACR_PREFER_PUBLIC, "").strip().lower() \
|
|
301
|
+
in ("1", "true", "on")
|
|
271
302
|
return Profile(name=name, api_env=env,
|
|
272
303
|
cluster=str(cluster_value).strip(),
|
|
273
304
|
storage_env=normalize_storage_env(storage_value),
|
|
274
305
|
metadata_model=(metadata_model or "").strip(),
|
|
306
|
+
prefer_public_registry=bool(prefer_public),
|
|
275
307
|
sources=sources, **cfg)
|
|
276
308
|
|
|
277
309
|
|
|
@@ -323,6 +355,8 @@ def fetch_repo_config(transport, *, cluster: str = "", storage_env: str = "") ->
|
|
|
323
355
|
if acr := data.get("acr"):
|
|
324
356
|
if acr.get("registry"):
|
|
325
357
|
result["acr_host"] = acr["registry"]
|
|
358
|
+
if acr.get("public_registry"):
|
|
359
|
+
result["acr_public_host"] = acr["public_registry"]
|
|
326
360
|
if acr.get("namespace"):
|
|
327
361
|
result["acr_namespace"] = acr["namespace"]
|
|
328
362
|
# api_env 由 apiserver 在 repo-config 响应中下发(omitempty,旧版不返回)。
|
|
@@ -48,7 +48,7 @@ class ImageClient:
|
|
|
48
48
|
计算**目标环境**的引用,配合 :meth:`copy` 做跨环境搬运。
|
|
49
49
|
"""
|
|
50
50
|
host = acr_host or bootstrap.require(
|
|
51
|
-
self._p, "
|
|
51
|
+
self._p, "effective_acr_host", action="拼 ACR 镜像引用")
|
|
52
52
|
ns = namespace or bootstrap.require(
|
|
53
53
|
self._p, "acr_namespace", action="拼 ACR 镜像引用")
|
|
54
54
|
return self._layout(metadata_model).image_ref(
|
|
@@ -377,7 +377,7 @@ class InstancesClient:
|
|
|
377
377
|
if push_image:
|
|
378
378
|
# 自带 tar 且会推 ACR:docker_image 记它将被推到的 ACR 目标地址。
|
|
379
379
|
# 仅在 push_image 时记——否则该 ACR 地址指向从未推送过的镜像,是假的。
|
|
380
|
-
docker_ref = lay.image_ref(self._p.
|
|
380
|
+
docker_ref = lay.image_ref(self._p.effective_acr_host, self._p.acr_namespace,
|
|
381
381
|
dataset, instance_id,
|
|
382
382
|
version=version, split=split)
|
|
383
383
|
else:
|
|
@@ -399,7 +399,7 @@ class InstancesClient:
|
|
|
399
399
|
if image_release_dst_acr:
|
|
400
400
|
from .. import release as _R # 局部导入避免循环依赖
|
|
401
401
|
extend_meta = _R.image_release_meta(
|
|
402
|
-
docker_ref, self._p.
|
|
402
|
+
docker_ref, self._p.effective_acr_host, image_release_dst_acr)
|
|
403
403
|
|
|
404
404
|
# ② 写元数据(pending) → 拿稳定 id(register=False 时跳过,用本地 id)
|
|
405
405
|
meta = DatasetInstance(
|
|
@@ -702,6 +702,8 @@ class InstancesClient:
|
|
|
702
702
|
warm(sts_prefix)
|
|
703
703
|
# 推镜像时同样预热 ACR 凭据缓存(否则首轮各 worker 会并发重复签同一 host)
|
|
704
704
|
if push_image and getattr(self._p, "acr_host", None):
|
|
705
|
+
# 签名恒用 apiserver 登记的 host(acr_host,VPC);token 实例级,
|
|
706
|
+
# 对公网 endpoint 同样有效(prefer_public 时连接走公网、签名仍走这里)。
|
|
705
707
|
try:
|
|
706
708
|
self._t.get_acr_credentials(self._p.acr_host)
|
|
707
709
|
except Exception: # noqa: BLE001 — 预热失败不阻断,真正推镜像时再报
|
|
@@ -699,10 +699,10 @@ class VersionsClient:
|
|
|
699
699
|
kw.get("split", "default"))
|
|
700
700
|
kw["recorded_images"] = recorded
|
|
701
701
|
for iid, img in sorted(recorded.items()):
|
|
702
|
-
if img and not img.startswith(self._p.
|
|
702
|
+
if img and not img.startswith(self._p.effective_acr_host + "/"):
|
|
703
703
|
skipped.append({
|
|
704
704
|
"instance_id": iid, "image": img,
|
|
705
|
-
"reason": f"not on source ACR {self._p.
|
|
705
|
+
"reason": f"not on source ACR {self._p.effective_acr_host}; "
|
|
706
706
|
f"base/共享镜像不随数据集上架搬运",
|
|
707
707
|
})
|
|
708
708
|
wf = self.publish(dataset, version, instances=instances, images=images, **kw)
|
|
@@ -814,8 +814,8 @@ class VersionsClient:
|
|
|
814
814
|
raise SchemaError("images='on' 需要 instances 列表(镜像按实例枚举)")
|
|
815
815
|
image_dists = R.build_image_distributions(
|
|
816
816
|
dataset, version, instances,
|
|
817
|
-
src_acr=self._p.
|
|
818
|
-
dst_acr=dst.
|
|
817
|
+
src_acr=self._p.effective_acr_host, src_namespace=self._p.acr_namespace,
|
|
818
|
+
dst_acr=dst.effective_acr_host,
|
|
819
819
|
# 目标命名空间:v0.8 之前解析了 --target-acr-namespace 却只换 host,
|
|
820
820
|
# 该参数从未生效;这里真正把它传下去。为空则保留源命名空间(旧行为)。
|
|
821
821
|
dst_namespace=dst.acr_namespace,
|
|
@@ -70,7 +70,9 @@ class Repo:
|
|
|
70
70
|
self._content = OssContentStore(
|
|
71
71
|
self.transport, self.profile.oss_bucket,
|
|
72
72
|
bucket_factory=bucket_factory)
|
|
73
|
-
self._image = AcrImageStore(
|
|
73
|
+
self._image = AcrImageStore(
|
|
74
|
+
self.transport, runner=runner,
|
|
75
|
+
prefer_public=self.profile.prefer_public_registry)
|
|
74
76
|
# 读路径必须与写路径对称下发 environment 与 metadata_model:
|
|
75
77
|
# ingest 按 storage_env 写 pre 集合、默认 split_first,读若不下发会查 online/
|
|
76
78
|
# version_first 而闭环断裂(历史真实缺陷,见 store/registry.py)。
|
|
@@ -308,8 +310,8 @@ class Repo:
|
|
|
308
310
|
raise SchemaError(
|
|
309
311
|
"rewrite_task_toml_image 需要目标 oss_bucket(用 target_overrides 提供),"
|
|
310
312
|
"否则无法把改写后的 content.tgz 直传目标桶")
|
|
311
|
-
src_acr = self.profile.
|
|
312
|
-
dst_acr = dst.
|
|
313
|
+
src_acr = self.profile.effective_acr_host
|
|
314
|
+
dst_acr = dst.effective_acr_host
|
|
313
315
|
dst_ns = dst.acr_namespace
|
|
314
316
|
|
|
315
317
|
# instance_id → 本地目录(仅 harbor 目录;SWE 是 .json 文件,没有 task.toml)
|
|
@@ -192,10 +192,15 @@ def _pin_digest(ref: str, digest: str) -> str:
|
|
|
192
192
|
|
|
193
193
|
|
|
194
194
|
class AcrImageStore(BaseImageStore):
|
|
195
|
-
def __init__(self, transport, *, runner: Runner | None = None
|
|
195
|
+
def __init__(self, transport, *, runner: Runner | None = None,
|
|
196
|
+
prefer_public: bool = False) -> None:
|
|
196
197
|
self._t = transport
|
|
197
198
|
self._injected_runner = runner is not None
|
|
198
199
|
self._run = runner or _default_runner
|
|
200
|
+
# prefer_public:runner 不在 VPC 内网时置 True(对应 profile.prefer_public_registry)。
|
|
201
|
+
# 连接优先公网 endpoint;凭据签名仍用 private canonical host(apiserver acr_profiles
|
|
202
|
+
# 只登记 VPC host,GetAuthorizationToken 的 token 是实例级、对两个 endpoint 通用)。
|
|
203
|
+
self._prefer_public = prefer_public
|
|
199
204
|
|
|
200
205
|
def _deadline(self) -> float:
|
|
201
206
|
return time.monotonic() + _DEFAULT_OPERATION_DEADLINE_SECONDS
|
|
@@ -225,9 +230,13 @@ class AcrImageStore(BaseImageStore):
|
|
|
225
230
|
host = _registry_host(ref)
|
|
226
231
|
route = _plan_acr_route(host)
|
|
227
232
|
canonical = _with_host(ref, route.private_endpoint)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
candidates
|
|
233
|
+
if self._prefer_public and route.public_endpoint \
|
|
234
|
+
and route.public_endpoint != route.private_endpoint:
|
|
235
|
+
candidates = [_with_host(ref, route.public_endpoint), canonical]
|
|
236
|
+
else:
|
|
237
|
+
candidates = [canonical]
|
|
238
|
+
if route.public_endpoint and route.public_endpoint != route.private_endpoint:
|
|
239
|
+
candidates.append(_with_host(ref, route.public_endpoint))
|
|
231
240
|
return canonical, tuple(candidates)
|
|
232
241
|
|
|
233
242
|
def _net_ref(self, ref: str) -> str:
|
|
@@ -413,11 +422,14 @@ class AcrImageStore(BaseImageStore):
|
|
|
413
422
|
def pull(self, ref: str, tar_path: Path, *, overwrite: bool = False) -> str:
|
|
414
423
|
"""把远端镜像拉到本地 docker-archive tar;返回实际拉取的 digest 固定引用。
|
|
415
424
|
|
|
416
|
-
与 OSS 下载同口径:``pull``
|
|
425
|
+
与 OSS 下载同口径:``pull`` 是**下载动作,默认强制私网**——只用私网候选,不做公网回退。
|
|
417
426
|
私网端点无法确认为标准 ACR 私网地址(自定义 registry),或私网连通性失败时,抛
|
|
418
427
|
``PrivateNetworkRequired``,绝不静默走公网。
|
|
419
428
|
|
|
420
|
-
|
|
429
|
+
例外:构造时 ``prefer_public=True``(IR_ACR_PREFER_PUBLIC=1,runner 不在 VPC 内网)
|
|
430
|
+
时改走**公网 endpoint**(仍经标准 ACR 确认;凭据仍用 VPC host 签,token 实例级通用)。
|
|
431
|
+
|
|
432
|
+
源引用先经 inspect 取得不可变 digest 并以 digest 固定后再拉,避免 tag 在
|
|
421
433
|
inspect 与 copy 之间被覆盖、导致拉到非预期镜像。
|
|
422
434
|
"""
|
|
423
435
|
deadline = self._deadline()
|
|
@@ -428,26 +440,29 @@ class AcrImageStore(BaseImageStore):
|
|
|
428
440
|
"download requires private data-plane access; registry "
|
|
429
441
|
f"{_registry_host(ref)} cannot be confirmed as a standard "
|
|
430
442
|
"private ACR endpoint; public fallback is disabled")
|
|
431
|
-
|
|
443
|
+
if self._prefer_public:
|
|
444
|
+
data_ref = _with_host(ref, route.public_endpoint)
|
|
445
|
+
else:
|
|
446
|
+
data_ref = _with_host(ref, route.private_endpoint)
|
|
432
447
|
|
|
433
|
-
authfile = self._authfile(
|
|
448
|
+
authfile = self._authfile(data_ref, credentials=credentials)
|
|
434
449
|
try:
|
|
435
|
-
inspected = self._inspect(
|
|
450
|
+
inspected = self._inspect(data_ref, authfile, deadline)
|
|
436
451
|
finally:
|
|
437
452
|
self._cleanup(authfile)
|
|
438
453
|
if inspected.state is _InspectState.ERROR:
|
|
439
|
-
error = self._inspect_error(
|
|
454
|
+
error = self._inspect_error(data_ref, inspected, authfile)
|
|
440
455
|
if _is_skopeo_connectivity_error(inspected.stderr):
|
|
441
456
|
raise PrivateNetworkRequired(
|
|
442
|
-
"download
|
|
443
|
-
f"
|
|
457
|
+
"download data-plane access failed; registry "
|
|
458
|
+
f"{_registry_host(data_ref)} is unreachable; "
|
|
444
459
|
"public fallback is disabled", cause=error)
|
|
445
460
|
raise error
|
|
446
461
|
if inspected.state is _InspectState.ABSENT:
|
|
447
|
-
raise TransportError(f"source image manifest not found: {
|
|
462
|
+
raise TransportError(f"source image manifest not found: {data_ref}")
|
|
448
463
|
if inspected.digest is None:
|
|
449
464
|
raise TransportError(
|
|
450
|
-
f"source inspect returned no immutable digest: {
|
|
465
|
+
f"source inspect returned no immutable digest: {data_ref}")
|
|
451
466
|
|
|
452
467
|
target = Path(tar_path)
|
|
453
468
|
if target.exists() and not overwrite:
|
|
@@ -456,7 +471,7 @@ class AcrImageStore(BaseImageStore):
|
|
|
456
471
|
if target.parent and not target.parent.exists():
|
|
457
472
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
458
473
|
|
|
459
|
-
pinned = _pin_digest(
|
|
474
|
+
pinned = _pin_digest(data_ref, inspected.digest)
|
|
460
475
|
authfile = self._authfile(pinned, credentials=credentials)
|
|
461
476
|
try:
|
|
462
477
|
command = self._run_command(
|
|
@@ -470,8 +485,8 @@ class AcrImageStore(BaseImageStore):
|
|
|
470
485
|
"skopeo copy(reg→archive) failed", command.stderr, authfile)
|
|
471
486
|
if _is_skopeo_connectivity_error(command.stderr):
|
|
472
487
|
raise PrivateNetworkRequired(
|
|
473
|
-
"download
|
|
474
|
-
f"
|
|
488
|
+
"download data-plane access failed; registry "
|
|
489
|
+
f"{_registry_host(data_ref)} is unreachable; "
|
|
475
490
|
"public fallback is disabled", cause=cause)
|
|
476
491
|
raise cause
|
|
477
492
|
finally:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: instance-repo
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: InstanceRepo SDK — 评测 Instance 统一存储客户端(SDK-only;控制面由 apiserver 承载)
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -58,6 +58,12 @@ pip install "instance-repo[oss]" # 需要数据面 OSS 读写时,附带 os
|
|
|
58
58
|
`profile_overrides={"acr_namespace": ...}`;默认 namespace 由 repo-config 返回,但**必须由部署方
|
|
59
59
|
在 ACR 企业版实例中预建**,SDK 不会创建)。
|
|
60
60
|
|
|
61
|
+
**公网 ACR registry(runner 不在 VPC 内网时)**:默认使用 repo-config 返回的 `registry`
|
|
62
|
+
(VPC 内网域名)。runner 不在对应 VPC 内时,设环境变量 `IR_ACR_PREFER_PUBLIC=1`(或
|
|
63
|
+
`Repo(profile_overrides={"prefer_public_registry": True})`),SDK 会改走 `public_registry`
|
|
64
|
+
(公网域名);公网值缺失时静默回落到 VPC 值。也可用 `IR_ACR_PUBLIC_HOST` /
|
|
65
|
+
`profile_overrides={"acr_public_host": ...}` 显式指定公网 registry。
|
|
66
|
+
|
|
61
67
|
兼容别名表:
|
|
62
68
|
|
|
63
69
|
| 旧名 | 新名或状态 | 优先级 | 告警 |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{instance_repo-1.3.0.dev0 → instance_repo-1.3.1}/instance_repo.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|