Add versioned daemon protocol envelope
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
|
||||||
|
# Development backups
|
||||||
|
*.pre-*
|
||||||
|
*.bak
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
|
||||||
|
# Accidental test-output files
|
||||||
|
/-INFINITY
|
||||||
|
/100
|
||||||
+58
-14
@@ -17,34 +17,76 @@ SOCKET_PATH = os.environ.get(
|
|||||||
server_socket = None
|
server_socket = None
|
||||||
registry = None
|
registry = None
|
||||||
|
|
||||||
|
PROTOCOL_VERSION = 1
|
||||||
|
|
||||||
|
|
||||||
|
def protocol_response(payload):
|
||||||
|
"""
|
||||||
|
Return a daemon response carrying the wire-protocol version.
|
||||||
|
|
||||||
|
protocol_version is daemon-owned metadata and cannot be overridden by
|
||||||
|
registry or plugin output.
|
||||||
|
"""
|
||||||
|
response = dict(payload)
|
||||||
|
response["protocol_version"] = PROTOCOL_VERSION
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def handle_request(req):
|
def handle_request(req):
|
||||||
|
if not isinstance(req, dict):
|
||||||
|
return protocol_response({
|
||||||
|
"ok": False,
|
||||||
|
"error_code": "invalid_request",
|
||||||
|
"error": "request must be a JSON object",
|
||||||
|
})
|
||||||
|
|
||||||
|
requested_version = req.get("protocol_version")
|
||||||
|
|
||||||
|
# Backward compatibility for the pre-versioned proxy:
|
||||||
|
# absence is accepted during the rolling upgrade, but an explicitly
|
||||||
|
# incompatible version is rejected.
|
||||||
|
if (
|
||||||
|
requested_version is not None
|
||||||
|
and requested_version != PROTOCOL_VERSION
|
||||||
|
):
|
||||||
|
return protocol_response({
|
||||||
|
"ok": False,
|
||||||
|
"error_code": "unsupported_protocol_version",
|
||||||
|
"error": (
|
||||||
|
"unsupported protocol version: "
|
||||||
|
f"{requested_version}; "
|
||||||
|
f"supported={PROTOCOL_VERSION}"
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
action = req.get("action")
|
action = req.get("action")
|
||||||
|
|
||||||
if action == "ping":
|
if action == "ping":
|
||||||
return {
|
return protocol_response({
|
||||||
"ok": True,
|
"ok": True,
|
||||||
"daemon": "managed-containerd",
|
"daemon": "managed-containerd",
|
||||||
"protocol_version": 1,
|
})
|
||||||
}
|
|
||||||
|
|
||||||
if action == "registry.list":
|
if action == "registry.list":
|
||||||
return {
|
return protocol_response({
|
||||||
"ok": True,
|
"ok": True,
|
||||||
"resources": registry.list_resources(),
|
"resources": registry.list_resources(),
|
||||||
}
|
})
|
||||||
|
|
||||||
resource = req.get("resource")
|
resource = req.get("resource")
|
||||||
|
|
||||||
if not resource:
|
if not resource:
|
||||||
return {
|
return protocol_response({
|
||||||
"ok": False,
|
"ok": False,
|
||||||
|
"error_code": "invalid_request",
|
||||||
"error": "resource is required",
|
"error": "resource is required",
|
||||||
}
|
})
|
||||||
|
|
||||||
return registry.execute(
|
return protocol_response(
|
||||||
resource,
|
registry.execute(
|
||||||
action,
|
resource,
|
||||||
|
action,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -136,18 +178,20 @@ def serve():
|
|||||||
ValueError,
|
ValueError,
|
||||||
KeyError,
|
KeyError,
|
||||||
) as exc:
|
) as exc:
|
||||||
response = {
|
response = protocol_response({
|
||||||
"ok": False,
|
"ok": False,
|
||||||
|
"error_code": "request_error",
|
||||||
"error": str(exc),
|
"error": str(exc),
|
||||||
}
|
})
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
response = {
|
response = protocol_response({
|
||||||
"ok": False,
|
"ok": False,
|
||||||
|
"error_code": "internal_error",
|
||||||
"error": str(exc),
|
"error": str(exc),
|
||||||
}
|
})
|
||||||
|
|
||||||
conn.sendall(
|
conn.sendall(
|
||||||
json.dumps(
|
json.dumps(
|
||||||
|
|||||||
Reference in New Issue
Block a user