gowalk-cicd 1.0.210 → 1.0.211
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.
package/README.md
CHANGED
|
@@ -1395,6 +1395,9 @@ Backend Deploy also offers `operation: network-diagnostics`, with an exact `diag
|
|
|
1395
1395
|
It reports the owned bridge/IPAM, observed pool conflicts, UDP 500/4500 ownership, bound host identity and
|
|
1396
1396
|
kernel/firewall facts in a closed v3 artifact for IPv4 and v4 for IPv6. The IPv6 result also distinguishes
|
|
1397
1397
|
host and owned-gateway default-route and forwarding observations; actual external connectivity stays unverified.
|
|
1398
|
+
Its artifact also retains a separate `transport.json` with the SSH exit status and fixed failure signals,
|
|
1399
|
+
including an observed gate refusal, without private transport output. These observations do not establish the
|
|
1400
|
+
installed host reader or the reason its gate refused; the network result and refusal retain their existing meaning.
|
|
1398
1401
|
The allocator stays retired; a completed read is never
|
|
1399
1402
|
deployment, port reservation, globally unused address space or tunnel proof. Effective firewall ingress and
|
|
1400
1403
|
unobserved capabilities remain unverified. The [trusted-host procedure](docs/BACKEND_SSH_GATE.md#owned-bridge-and-vpn-prerequisite-readback)
|
|
@@ -341,11 +341,12 @@ runs:
|
|
|
341
341
|
run: |
|
|
342
342
|
RESULT_DIR="$(mktemp -d "$RUNNER_TEMP/backend-network-diagnostics.XXXXXX")"
|
|
343
343
|
echo "result=$RESULT_DIR/result.json" >> "$GITHUB_OUTPUT"
|
|
344
|
+
echo "transport=$RESULT_DIR/transport.json" >> "$GITHUB_OUTPUT"
|
|
344
345
|
python3 "${{ github.action_path }}/network_diagnostics.py" \
|
|
345
346
|
--app "$DIAGNOSTIC_APP" --service "$DIAGNOSTIC_SERVICE" --expected-build-sha "$DIAGNOSTIC_BUILD" \
|
|
346
347
|
--network "$DIAGNOSTIC_NETWORK" --pool "$DIAGNOSTIC_POOL" --vpn-service "$DIAGNOSTIC_VPN_SERVICE" \
|
|
347
348
|
--host "$DIAGNOSTIC_HOST" --user "$DIAGNOSTIC_USER" --provider "$DIAGNOSTIC_PROVIDER" \
|
|
348
|
-
--output "$RESULT_DIR/result.json"
|
|
349
|
+
--output "$RESULT_DIR/result.json" --transport-output "$RESULT_DIR/transport.json"
|
|
349
350
|
|
|
350
351
|
- name: Retain scoped backend network result
|
|
351
352
|
if: always() && inputs.operation == 'network-diagnostics'
|
|
@@ -354,7 +355,9 @@ runs:
|
|
|
354
355
|
NODE_OPTIONS: --require "${{ github.action_path }}/scripts/artifact_env.cjs"
|
|
355
356
|
with:
|
|
356
357
|
name: backend-network-diagnostics-${{ github.job }}-${{ github.run_attempt }}
|
|
357
|
-
path:
|
|
358
|
+
path: |
|
|
359
|
+
${{ steps.network_diagnostics.outputs.result }}
|
|
360
|
+
${{ steps.network_diagnostics.outputs.transport }}
|
|
358
361
|
if-no-files-found: error
|
|
359
362
|
|
|
360
363
|
- name: Cleanup key
|
|
@@ -3,13 +3,15 @@ import argparse
|
|
|
3
3
|
import json
|
|
4
4
|
import re
|
|
5
5
|
import shlex
|
|
6
|
+
import sys
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
from identity_diagnostics import ReaderFailure, bounded, retain_result
|
|
9
10
|
from network_projection import NetworkFailure, envelope, scope, validate
|
|
11
|
+
from runtime_diagnostics import transport_signals
|
|
10
12
|
|
|
11
13
|
|
|
12
|
-
def local(args):
|
|
14
|
+
def local(args, transport=None):
|
|
13
15
|
fields = (args.app, args.service, args.expected_build_sha, args.network, args.pool,
|
|
14
16
|
args.vpn_service, args.host, args.provider)
|
|
15
17
|
scope(*fields)
|
|
@@ -17,14 +19,17 @@ def local(args):
|
|
|
17
19
|
raise NetworkFailure('invalid_scope')
|
|
18
20
|
command = shlex.join(['gowalk-backend', 'network-diagnostics', *fields])
|
|
19
21
|
try:
|
|
20
|
-
status, raw = bounded(['ssh', '-T', '-i', str(Path.home() / '.ssh/backend_deploy'),
|
|
22
|
+
status, raw, errors = bounded(['ssh', '-T', '-i', str(Path.home() / '.ssh/backend_deploy'),
|
|
21
23
|
'-o', 'IdentitiesOnly=yes', '-o', 'BatchMode=yes', '-o', 'StrictHostKeyChecking=yes',
|
|
22
24
|
'-o', 'ConnectTimeout=10', '-o', 'ServerAliveInterval=5', '-o', 'ServerAliveCountMax=2',
|
|
23
|
-
'-o', 'ClearAllForwardings=yes', args.user + '@' + args.host, command],
|
|
25
|
+
'-o', 'ClearAllForwardings=yes', args.user + '@' + args.host, command],
|
|
26
|
+
seconds=120, with_status=True, with_stderr=True)
|
|
24
27
|
except ReaderFailure as error:
|
|
25
28
|
raise NetworkFailure(error.code) from None
|
|
26
29
|
except OSError:
|
|
27
30
|
raise NetworkFailure('transport_failure') from None
|
|
31
|
+
if transport is not None:
|
|
32
|
+
transport.update(exit_status=status, signals=transport_signals(status, errors))
|
|
28
33
|
if status not in (0, 1):
|
|
29
34
|
raise NetworkFailure('transport_failure')
|
|
30
35
|
if status == 1 and not raw.strip():
|
|
@@ -45,16 +50,24 @@ def main():
|
|
|
45
50
|
for name, default in [('service', 'api'), ('network', 'default'), ('vpn-service', 'vpn'),
|
|
46
51
|
('provider', 'none'), ('user', 'root')]:
|
|
47
52
|
parser.add_argument('--' + name, default=default)
|
|
53
|
+
parser.add_argument('--transport-output', help='Separate closed SSH observation receipt')
|
|
48
54
|
args = parser.parse_args()
|
|
49
55
|
fields = (args.app, args.service, args.expected_build_sha, args.network, args.pool,
|
|
50
56
|
args.vpn_service, args.host, args.provider)
|
|
57
|
+
transport = {'schema': 'gowalk-cicd/backend-network-transport.v1', 'exit_status': None, 'signals': []}
|
|
51
58
|
try:
|
|
52
|
-
result = local(args)
|
|
59
|
+
result = local(args, transport)
|
|
53
60
|
except Exception as error:
|
|
54
61
|
result = envelope(*fields, failure=error.code if isinstance(error, NetworkFailure) else 'unclassified',
|
|
55
62
|
reader_version=None)
|
|
56
63
|
try:
|
|
57
64
|
retain_result(args.output, result)
|
|
65
|
+
if args.transport_output:
|
|
66
|
+
retain_result(args.transport_output, transport)
|
|
67
|
+
status = 'unknown' if transport['exit_status'] is None else str(transport['exit_status'])
|
|
68
|
+
print('::notice title=backend_network_transport::schema=' + transport['schema']
|
|
69
|
+
+ ' exit_status=' + status + ' signals=' + (','.join(transport['signals']) or 'none'),
|
|
70
|
+
file=sys.stderr)
|
|
58
71
|
except ReaderFailure:
|
|
59
72
|
result = envelope(*fields, failure='artifact_write_failed', reader_version=None)
|
|
60
73
|
print(json.dumps(result, separators=(',', ':')))
|
package/docs/BACKEND_SSH_GATE.md
CHANGED
|
@@ -123,6 +123,14 @@ released `network_readback.py`. It accepts no uploaded Python or app-mirror help
|
|
|
123
123
|
alone cannot install this host operation: install the integrity-verified published runtime first. A missing
|
|
124
124
|
host reader returns `network_reader_unavailable` with no host reader version; it is not a network verdict.
|
|
125
125
|
|
|
126
|
+
The same artifact retains `transport.json`, schema `gowalk-cicd/backend-network-transport.v1`, and emits the
|
|
127
|
+
brace-free `backend_network_transport` notice. It uses the runtime diagnostic's fixed `exit_status` and
|
|
128
|
+
`signals` vocabulary described above; no private stderr is retained. In particular, SSH exit 1 with empty
|
|
129
|
+
stdout still yields `network_reader_unavailable`, while the separate `gate_refused` signal records an observed
|
|
130
|
+
gate refusal without guessing its policy, ownership or installed-reader cause. An incomplete SSH exit remains
|
|
131
|
+
null, and unknown text supplies no signal. Neither this sidecar nor a workflow update proves host adoption or
|
|
132
|
+
authorizes a retry, permission change or transport bypass; the existing result schema and refusal remain unchanged.
|
|
133
|
+
|
|
126
134
|
The closed `gowalk-cicd/backend-network-diagnostics.v3` IPv4 result, or `v4` for IPv6, is retained as
|
|
127
135
|
`backend-network-diagnostics-<job>-<attempt>/result.json`. `ok: true` means the bounded read completed;
|
|
128
136
|
it never means a VPN is provisioned, traffic is reachable, a pool is globally unused or a tunnel works.
|