#!/usr/bin/env python3 import json import os import tempfile from pathlib import Path from unittest.mock import patch from registry import Registry PLUGIN_SOURCE = r""" def notify(config, runtime_state, request_parameters): runtime_state["postgresql"] = { "notification": dict(request_parameters), "reconnect_started_at": 123.4, "state_changed_at": 567.8, } return { "ocf_rc": 0, } """ def require(condition, message): if not condition: raise SystemExit("FAIL: " + message) print("===== DAEMON STATE PERSISTENCE =====") with tempfile.TemporaryDirectory() as temporary_root: root = Path(temporary_root) plugin_root = root / "plugins" / "fake" plugin_root.mkdir(parents=True) (plugin_root / "manifest.json").write_text( json.dumps({ "name": "fake", "version": 1, "module": "plugin.py", "actions": ["notify"], "required_config": [], }) ) (plugin_root / "plugin.py").write_text(PLUGIN_SOURCE) state_dir = root / "state" environment = { "MANAGED_CONTAINERD_PLUGIN_ROOT": str( root / "plugins" ), "MANAGED_CONTAINERD_STATE_DIR": str(state_dir), "RESOURCE_ID": "fake-resource", "PLUGIN": "fake", } parameters = { "type": "pre", "operation": "demote", "promote_uname": "david-eve", } with patch.dict(os.environ, environment, clear=False): first = Registry() result = first.execute( "fake-resource", "notify", parameters, ) require( result["result"]["ocf_rc"] == 0, "initial notify failed", ) files = list(state_dir.glob("*.json")) require( len(files) == 1, "state file was not created", ) mode = files[0].stat().st_mode & 0o777 require( mode == 0o600, "state file is not mode 0600", ) saved = json.loads(files[0].read_text()) require( saved["postgresql"]["notification"] == parameters, "notification was not persisted", ) require( "reconnect_started_at" not in saved["postgresql"], "volatile reconnect state was persisted", ) require( "state_changed_at" not in saved["postgresql"], "volatile monotonic state was persisted", ) print("atomic_state_write persisted") second = Registry() restored = second.resources[ "fake-resource" ].runtime_state require( restored["postgresql"]["notification"] == parameters, "notification was not restored", ) print("restart_state_load restored") print() print("STATE_PERSISTENCE_TEST_PASS=1")