socaity-cli 0.1.4__tar.gz → 0.1.5__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.
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/PKG-INFO +1 -1
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/pyproject.toml +1 -1
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/registry_push.py +12 -1
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/PKG-INFO +1 -1
- socaity_cli-0.1.5/test/test_registry_push.py +32 -0
- socaity_cli-0.1.4/test/test_registry_push.py +0 -12
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/README.md +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/setup.cfg +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/__init__.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/__main__.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/apipod_commands.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/auth.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/backend_client.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/cli.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/__init__.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/analytics.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/catalog.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/deployment.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/files.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/jobs.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/projects.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/clients/sdk_install.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/credentials.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/deployment.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/errors.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/http.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/prompts.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/requires.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli/sdk_commands.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/SOURCES.txt +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/dependency_links.txt +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/entry_points.txt +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/requires.txt +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/socaity_cli.egg-info/top_level.txt +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/test/test_cli.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/test/test_credentials.py +0 -0
- {socaity_cli-0.1.4 → socaity_cli-0.1.5}/test/test_private_slot_error.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "socaity-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "Socaity platform CLI: login, catalog browsing, SDK installs and APIPod deployment commands."
|
|
9
9
|
requires-python = ">=3.8"
|
|
10
10
|
authors = [
|
|
@@ -41,6 +41,17 @@ def is_transient_push_error(message: str) -> bool:
|
|
|
41
41
|
return any(marker in lower for marker in _TRANSIENT_PUSH_MARKERS)
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
def _push_command(ref: str) -> list:
|
|
45
|
+
"""``docker push`` args. Docker 25+ dropped ``--max-concurrent-uploads``."""
|
|
46
|
+
help_out = _docker(["push", "--help"])
|
|
47
|
+
help_text = (help_out.stdout or b"").decode() + (help_out.stderr or b"").decode()
|
|
48
|
+
args = ["docker", "push"]
|
|
49
|
+
if "--max-concurrent-uploads" in help_text:
|
|
50
|
+
args.append("--max-concurrent-uploads=1")
|
|
51
|
+
args.append(ref)
|
|
52
|
+
return args
|
|
53
|
+
|
|
54
|
+
|
|
44
55
|
def _docker(args: list, *, env: Optional[dict] = None, input_bytes: Optional[bytes] = None) -> subprocess.CompletedProcess:
|
|
45
56
|
try:
|
|
46
57
|
return subprocess.run(["docker", *args], capture_output=True, env=env, input=input_bytes)
|
|
@@ -96,7 +107,7 @@ def push_image(
|
|
|
96
107
|
raise PushFailed(f"docker login failed: {stderr[:300]}")
|
|
97
108
|
|
|
98
109
|
push = subprocess.Popen(
|
|
99
|
-
|
|
110
|
+
_push_command(ref),
|
|
100
111
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env, text=True,
|
|
101
112
|
)
|
|
102
113
|
digest, last_lines = None, []
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from socaity_cli.registry_push import _push_command, is_transient_push_error
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_is_transient_push_error_matches_harbor_timeouts():
|
|
5
|
+
assert is_transient_push_error(
|
|
6
|
+
'docker push failed: timeout awaiting response headers'
|
|
7
|
+
)
|
|
8
|
+
assert is_transient_push_error("client disconnected during blob PUT")
|
|
9
|
+
assert is_transient_push_error("unexpected EOF")
|
|
10
|
+
assert is_transient_push_error("connection reset by peer")
|
|
11
|
+
assert not is_transient_push_error("denied: requested access to the resource is denied")
|
|
12
|
+
assert not is_transient_push_error("")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_push_command_omits_unknown_max_concurrent_flag(monkeypatch):
|
|
16
|
+
class _Help:
|
|
17
|
+
stdout = b"Usage: docker push [OPTIONS] NAME[:TAG]\n"
|
|
18
|
+
stderr = b""
|
|
19
|
+
|
|
20
|
+
monkeypatch.setattr("socaity_cli.registry_push._docker", lambda args, **kwargs: _Help())
|
|
21
|
+
assert _push_command("harbor.example/repo:tag") == ["docker", "push", "harbor.example/repo:tag"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_push_command_uses_max_concurrent_when_supported(monkeypatch):
|
|
25
|
+
class _Help:
|
|
26
|
+
stdout = b" --max-concurrent-uploads int Max concurrent uploads\n"
|
|
27
|
+
stderr = b""
|
|
28
|
+
|
|
29
|
+
monkeypatch.setattr("socaity_cli.registry_push._docker", lambda args, **kwargs: _Help())
|
|
30
|
+
assert _push_command("harbor.example/repo:tag") == [
|
|
31
|
+
"docker", "push", "--max-concurrent-uploads=1", "harbor.example/repo:tag",
|
|
32
|
+
]
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from socaity_cli.registry_push import is_transient_push_error
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_is_transient_push_error_matches_harbor_timeouts():
|
|
5
|
-
assert is_transient_push_error(
|
|
6
|
-
'docker push failed: timeout awaiting response headers'
|
|
7
|
-
)
|
|
8
|
-
assert is_transient_push_error("client disconnected during blob PUT")
|
|
9
|
-
assert is_transient_push_error("unexpected EOF")
|
|
10
|
-
assert is_transient_push_error("connection reset by peer")
|
|
11
|
-
assert not is_transient_push_error("denied: requested access to the resource is denied")
|
|
12
|
-
assert not is_transient_push_error("")
|
|
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
|