зеркало из https://github.com/microsoft/CCF.git
remove set_js_app, {set|remove}_module & rename {deploy->set}_js_app (#2391)
This commit is contained in:
Родитель
c10b6e1c76
Коммит
f0e43aa99f
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Various endpoint-related types have moved under the `ccf::endpoints` namespace. Apps will need to rename these types where they are not using `auto`, for instance to `ccf::endpoints::EndpointContext` and `ccf::endpoints::ForwardingRequired`.
|
||||
- Ledger entry frames are no longer serialised with `msgpack` (#2343).
|
||||
- In JavaScript apps, the field `caller.jwt.key_issuer` in the `Request` object has been renamed `caller.jwt.keyIssuer` (#2362).
|
||||
- The proposals `set_module`, `remove_module` and `set_js_app` have been removed and `deploy_js_app` renamed to `set_js_app` (#2391).
|
||||
|
||||
## [0.19.3]
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Assuming the CCF Python package has been installed in the current Python environ
|
|||
|
||||
python -m ccf.proposal_generator
|
||||
usage: proposal_generator.py [-h] [-po PROPOSAL_OUTPUT_FILE] [-vo VOTE_OUTPUT_FILE] [-pp] [-i] [-v]
|
||||
{deploy_js_app,new_member,new_node_code,set_user,rekey_ledger,remove_ca_cert_bundle,remove_js_app,remove_jwt_issuer,remove_member,remove_module,remove_user,retire_node,retire_node_code,set_ca_cert_bundle,set_js_app,set_jwt_issuer,set_jwt_public_signing_keys,set_member_data,set_module,set_recovery_threshold,set_user_data,transition_service_to_open,trust_node,update_recovery_shares}
|
||||
{new_member,new_node_code,set_user,rekey_ledger,remove_ca_cert_bundle,remove_js_app,remove_jwt_issuer,remove_member,remove_user,retire_node,retire_node_code,set_ca_cert_bundle,set_js_app,set_jwt_issuer,set_jwt_public_signing_keys,set_member_data,set_recovery_threshold,set_user_data,transition_service_to_open,trust_node,update_recovery_shares}
|
||||
|
||||
Additional detail is available from the ``--help`` option. You can also find the script in a checkout of CCF:
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import os
|
|||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import PurePosixPath
|
||||
from typing import Union, Optional, Any, List, Dict
|
||||
|
||||
from cryptography import x509
|
||||
|
@ -331,17 +330,7 @@ def set_user_data(user_id: str, user_data: Any, **kwargs):
|
|||
|
||||
|
||||
@cli_proposal
|
||||
def set_js_app(app_script_path: str, **kwargs):
|
||||
LOG.error(
|
||||
"set_js_app proposal type is deprecated - update to use deploy_js_app instead"
|
||||
)
|
||||
with open(app_script_path) as f:
|
||||
app_script = f.read()
|
||||
return build_proposal("set_js_app", app_script, **kwargs)
|
||||
|
||||
|
||||
@cli_proposal
|
||||
def deploy_js_app(bundle_path: str, **kwargs):
|
||||
def set_js_app(bundle_path: str, **kwargs):
|
||||
# read modules
|
||||
if os.path.isfile(bundle_path):
|
||||
tmp_dir = tempfile.TemporaryDirectory(prefix="ccf")
|
||||
|
@ -369,7 +358,7 @@ def deploy_js_app(bundle_path: str, **kwargs):
|
|||
"bundle": {"metadata": metadata, "modules": modules},
|
||||
}
|
||||
|
||||
return build_proposal("deploy_js_app", proposal_args, **kwargs)
|
||||
return build_proposal("set_js_app", proposal_args, **kwargs)
|
||||
|
||||
|
||||
@cli_proposal
|
||||
|
@ -377,27 +366,6 @@ def remove_js_app(**kwargs):
|
|||
return build_proposal("remove_js_app", **kwargs)
|
||||
|
||||
|
||||
@cli_proposal
|
||||
def set_module(module_name: str, module_path: str, **kwargs):
|
||||
module_name_ = PurePosixPath(module_name)
|
||||
if not module_name_.is_absolute():
|
||||
raise ValueError("module name must be an absolute path")
|
||||
if any(folder in [".", ".."] for folder in module_name_.parents):
|
||||
raise ValueError("module name must not contain . or .. components")
|
||||
if module_name_.suffix == ".js":
|
||||
with open(module_path) as f:
|
||||
js = f.read()
|
||||
proposal_args = {"name": module_name, "module": js}
|
||||
else:
|
||||
raise ValueError("module name must end with .js")
|
||||
return build_proposal("set_module", proposal_args, **kwargs)
|
||||
|
||||
|
||||
@cli_proposal
|
||||
def remove_module(module_name: str, **kwargs):
|
||||
return build_proposal("remove_module", module_name, **kwargs)
|
||||
|
||||
|
||||
def read_modules(modules_path: str) -> List[dict]:
|
||||
modules = []
|
||||
for path in glob.glob(f"{modules_path}/**/*.js", recursive=True):
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace ccf
|
|||
}
|
||||
}
|
||||
|
||||
bool deploy_js_app(kv::Tx& tx, const JsBundle& bundle)
|
||||
bool set_js_app(kv::Tx& tx, const JsBundle& bundle)
|
||||
{
|
||||
std::string module_prefix = "/";
|
||||
remove_modules(tx, module_prefix);
|
||||
|
@ -334,36 +334,17 @@ namespace ccf
|
|||
std::string,
|
||||
std::function<bool(const ProposalId&, kv::Tx&, const nlohmann::json&)>>
|
||||
hardcoded_funcs = {
|
||||
// set the js application script
|
||||
// deploy the js application bundle
|
||||
{"set_js_app",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json& args) {
|
||||
const std::string app = args;
|
||||
set_js_scripts(tx, lua::Interpreter().invoke<nlohmann::json>(app));
|
||||
return true;
|
||||
}},
|
||||
// deploy the js application bundle
|
||||
{"deploy_js_app",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json& args) {
|
||||
const auto parsed = args.get<DeployJsApp>();
|
||||
return deploy_js_app(tx, parsed.bundle);
|
||||
return set_js_app(tx, parsed.bundle);
|
||||
}},
|
||||
// undeploy/remove the js application
|
||||
{"remove_js_app",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json&) {
|
||||
return remove_js_app(tx);
|
||||
}},
|
||||
// add/update a module
|
||||
{"set_module",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json& args) {
|
||||
const auto parsed = args.get<SetModule>();
|
||||
return set_module(tx, parsed.name, parsed.module);
|
||||
}},
|
||||
// remove a module
|
||||
{"remove_module",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json& args) {
|
||||
const auto name = args.get<std::string>();
|
||||
return remove_module(tx, name);
|
||||
}},
|
||||
// add a new member
|
||||
{"new_member",
|
||||
[this](const ProposalId&, kv::Tx& tx, const nlohmann::json& args) {
|
||||
|
|
|
@ -397,18 +397,8 @@ class Consortium:
|
|||
proposal = self.get_any_active_member().propose(remote_node, proposal)
|
||||
self.vote_using_majority(remote_node, proposal, careful_vote)
|
||||
|
||||
def set_js_app(self, remote_node, app_script_path):
|
||||
LOG.error(
|
||||
"set_js_app proposal type is deprecated - update to use deploy_js_app instead"
|
||||
)
|
||||
proposal_body, careful_vote = self.make_proposal("set_js_app", app_script_path)
|
||||
proposal = self.get_any_active_member().propose(remote_node, proposal_body)
|
||||
return self.vote_using_majority(remote_node, proposal, careful_vote)
|
||||
|
||||
def deploy_js_app(self, remote_node, app_bundle_path):
|
||||
proposal_body, careful_vote = self.make_proposal(
|
||||
"deploy_js_app", app_bundle_path
|
||||
)
|
||||
def set_js_app(self, remote_node, app_bundle_path):
|
||||
proposal_body, careful_vote = self.make_proposal("set_js_app", app_bundle_path)
|
||||
proposal = self.get_any_active_member().propose(remote_node, proposal_body)
|
||||
# Large apps take a long time to process - wait longer than normal for commit
|
||||
return self.vote_using_majority(remote_node, proposal, careful_vote, timeout=10)
|
||||
|
|
|
@ -114,7 +114,6 @@ def cli_args(add=lambda x: None, parser=None, accept_unknown=False):
|
|||
action="append",
|
||||
default=[],
|
||||
)
|
||||
parser.add_argument("-j", "--js-app-script", help="Path to js app script")
|
||||
parser.add_argument("--js-app-bundle", help="Path to js app bundle")
|
||||
parser.add_argument(
|
||||
"--jwt-issuer",
|
||||
|
@ -287,8 +286,7 @@ def cli_args(add=lambda x: None, parser=None, accept_unknown=False):
|
|||
else:
|
||||
args.library_dir = args.binary_dir
|
||||
|
||||
# js_app_script is deprecated
|
||||
if not args.package and (args.js_app_script or args.js_app_bundle):
|
||||
if not args.package and args.js_app_bundle:
|
||||
args.package = "libjs_generic"
|
||||
|
||||
if accept_unknown:
|
||||
|
|
|
@ -397,19 +397,8 @@ class Network:
|
|||
|
||||
self.consortium.activate(self.find_random_node())
|
||||
|
||||
if args.js_app_script:
|
||||
LOG.error(
|
||||
"--js-app-script is deprecated - update to --js-app-bundle instead"
|
||||
)
|
||||
infra.proc.ccall(
|
||||
"cp", args.js_app_script, args.binary_dir
|
||||
).check_returncode()
|
||||
self.consortium.set_js_app(
|
||||
remote_node=self.find_random_node(), app_script_path=args.js_app_script
|
||||
)
|
||||
|
||||
if args.js_app_bundle:
|
||||
self.consortium.deploy_js_app(
|
||||
self.consortium.set_js_app(
|
||||
remote_node=self.find_random_node(), app_bundle_path=args.js_app_bundle
|
||||
)
|
||||
|
||||
|
|
|
@ -24,17 +24,6 @@ THIS_DIR = os.path.dirname(__file__)
|
|||
PARENT_DIR = os.path.normpath(os.path.join(THIS_DIR, os.path.pardir))
|
||||
|
||||
|
||||
def make_module_set_proposal(module_path, file_path, network):
|
||||
primary, _ = network.find_nodes()
|
||||
proposal_body, careful_vote = ccf.proposal_generator.set_module(
|
||||
module_path, file_path
|
||||
)
|
||||
proposal = network.consortium.get_any_active_member().propose(
|
||||
primary, proposal_body
|
||||
)
|
||||
network.consortium.vote_using_majority(primary, proposal, careful_vote)
|
||||
|
||||
|
||||
def validate_openapi(client):
|
||||
api_response = client.get("/app/api")
|
||||
assert api_response.status_code == http.HTTPStatus.OK, api_response.status_code
|
||||
|
@ -49,42 +38,13 @@ def validate_openapi(client):
|
|||
raise e
|
||||
|
||||
|
||||
@reqs.description("Test module set and remove")
|
||||
def test_module_set_and_remove(network, args):
|
||||
primary, _ = network.find_nodes()
|
||||
|
||||
LOG.info("Member makes a module set proposal")
|
||||
bundle_dir = os.path.join(THIS_DIR, "basic-module-import")
|
||||
module_file_path = os.path.join(bundle_dir, "src", "foo.js")
|
||||
module_path = "/anything/you/want/when/setting/manually/dot/js.js"
|
||||
make_module_set_proposal(module_path, module_file_path, network)
|
||||
module_content = open(module_file_path, "r").read()
|
||||
|
||||
with primary.client(network.consortium.get_any_active_member().local_id) as c:
|
||||
r = c.post("/gov/read", {"table": "public:gov.modules", "key": module_path})
|
||||
assert r.status_code == http.HTTPStatus.OK, r.status_code
|
||||
assert r.body.json() == module_content, r.body
|
||||
|
||||
LOG.info("Member makes a module remove proposal")
|
||||
proposal_body, careful_vote = ccf.proposal_generator.remove_module(module_path)
|
||||
proposal = network.consortium.get_any_active_member().propose(
|
||||
primary, proposal_body
|
||||
)
|
||||
network.consortium.vote_using_majority(primary, proposal, careful_vote)
|
||||
|
||||
with primary.client(network.consortium.get_any_active_member().local_id) as c:
|
||||
r = c.post("/gov/read", {"table": "public:gov.modules", "key": module_path})
|
||||
assert r.status_code == http.HTTPStatus.NOT_FOUND, r.status_code
|
||||
return network
|
||||
|
||||
|
||||
@reqs.description("Test module import")
|
||||
def test_module_import(network, args):
|
||||
primary, _ = network.find_nodes()
|
||||
|
||||
# Update JS app, deploying modules _and_ app script that imports module
|
||||
bundle_dir = os.path.join(THIS_DIR, "basic-module-import")
|
||||
network.consortium.deploy_js_app(primary, bundle_dir)
|
||||
network.consortium.set_js_app(primary, bundle_dir)
|
||||
|
||||
with primary.client("user0") as c:
|
||||
r = c.post("/app/test_module", {})
|
||||
|
@ -106,7 +66,7 @@ def test_app_bundle(network, args):
|
|||
bundle_path = shutil.make_archive(
|
||||
os.path.join(tmp_dir, "bundle"), "zip", bundle_dir
|
||||
)
|
||||
network.consortium.deploy_js_app(primary, bundle_path)
|
||||
network.consortium.set_js_app(primary, bundle_path)
|
||||
|
||||
LOG.info("Verifying that modules and endpoints were added")
|
||||
with primary.client(network.consortium.get_any_active_member().local_id) as c:
|
||||
|
@ -154,7 +114,7 @@ def test_dynamic_endpoints(network, args):
|
|||
bundle_dir = os.path.join(PARENT_DIR, "js-app-bundle")
|
||||
|
||||
LOG.info("Deploying initial js app bundle archive")
|
||||
network.consortium.deploy_js_app(primary, bundle_dir)
|
||||
network.consortium.set_js_app(primary, bundle_dir)
|
||||
|
||||
valid_body = {"op": "sub", "left": 82, "right": 40}
|
||||
expected_response = {"result": 42}
|
||||
|
@ -195,7 +155,7 @@ def test_dynamic_endpoints(network, args):
|
|||
]
|
||||
with open(metadata_path, "w") as f:
|
||||
json.dump(metadata, f, indent=2)
|
||||
network.consortium.deploy_js_app(primary, modified_bundle_dir)
|
||||
network.consortium.set_js_app(primary, modified_bundle_dir)
|
||||
|
||||
LOG.info("Checking modified endpoint is accessible without auth")
|
||||
with primary.client() as c:
|
||||
|
@ -232,7 +192,7 @@ def test_npm_app(network, args):
|
|||
|
||||
LOG.info("Deploying npm app")
|
||||
bundle_dir = os.path.join(app_dir, "dist")
|
||||
network.consortium.deploy_js_app(primary, bundle_dir)
|
||||
network.consortium.set_js_app(primary, bundle_dir)
|
||||
|
||||
LOG.info("Calling npm app endpoints")
|
||||
with primary.client("user0") as c:
|
||||
|
@ -411,7 +371,6 @@ def run(args):
|
|||
args.nodes, args.binary_dir, args.debug_nodes, args.perf_nodes, pdb=args.pdb
|
||||
) as network:
|
||||
network.start_and_join(args)
|
||||
network = test_module_set_and_remove(network, args)
|
||||
network = test_module_import(network, args)
|
||||
network = test_app_bundle(network, args)
|
||||
network = test_dynamic_endpoints(network, args)
|
||||
|
|
Загрузка…
Ссылка в новой задаче