2023-06-27 22:58:41 +00:00
|
|
|
# Copyright © 2022, 2023 Cerc
|
|
|
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
|
|
|
|
2023-07-24 02:54:05 +00:00
|
|
|
from app.util import get_yaml
|
2023-08-08 19:03:10 +00:00
|
|
|
from app.deploy_types import DeployCommandContext, LaconicStackSetupCommand
|
2023-07-24 02:54:05 +00:00
|
|
|
from app.stack_state import State
|
2023-07-30 04:38:46 +00:00
|
|
|
from app.deploy_util import VolumeMapping, run_container_command
|
2023-08-08 19:03:10 +00:00
|
|
|
from enum import Enum
|
|
|
|
from pathlib import Path
|
|
|
|
import os
|
|
|
|
import sys
|
2023-08-09 03:06:44 +00:00
|
|
|
import tomli
|
2023-07-24 02:54:05 +00:00
|
|
|
|
|
|
|
default_spec_file_content = """config:
|
|
|
|
node_moniker: my-node-name
|
|
|
|
chain_id: my-chain-id
|
|
|
|
"""
|
|
|
|
|
|
|
|
init_help_text = """Add helpful text here on setting config variables.
|
2023-06-27 22:58:41 +00:00
|
|
|
"""
|
|
|
|
|
2023-07-24 02:54:05 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
class SetupPhase(Enum):
|
|
|
|
INITIALIZE = 1
|
|
|
|
JOIN = 2
|
|
|
|
CREATE = 3
|
|
|
|
ILLEGAL = 3
|
|
|
|
|
|
|
|
|
2023-08-15 11:13:35 +00:00
|
|
|
def _config_toml_path(network_dir: Path):
|
|
|
|
return network_dir.joinpath("config","client.toml")
|
|
|
|
|
2023-08-22 03:11:30 +00:00
|
|
|
|
2023-08-15 11:13:35 +00:00
|
|
|
def _get_chain_id_from_config(network_dir: Path):
|
2023-08-09 03:06:44 +00:00
|
|
|
chain_id = None
|
2023-08-15 11:13:35 +00:00
|
|
|
with open(_config_toml_path(network_dir), "rb") as f:
|
2023-08-09 03:06:44 +00:00
|
|
|
toml_dict = tomli.load(f)
|
2023-08-09 14:20:08 +00:00
|
|
|
chain_id = toml_dict["chain-id"]
|
2023-08-09 03:06:44 +00:00
|
|
|
return chain_id
|
|
|
|
|
|
|
|
|
2023-08-15 11:13:35 +00:00
|
|
|
def _get_node_moniker_from_config(network_dir: Path):
|
2023-08-09 03:06:44 +00:00
|
|
|
moniker = None
|
2023-08-15 11:13:35 +00:00
|
|
|
with open(_config_toml_path(network_dir), "rb") as f:
|
2023-08-09 03:06:44 +00:00
|
|
|
toml_dict = tomli.load(f)
|
|
|
|
moniker = toml_dict["moniker"]
|
|
|
|
return moniker
|
|
|
|
|
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
def setup(command_context: DeployCommandContext, parameters: LaconicStackSetupCommand, extra_args):
|
|
|
|
|
|
|
|
print(f"parameters: {parameters}")
|
|
|
|
|
|
|
|
phase = SetupPhase.ILLEGAL
|
|
|
|
|
|
|
|
if parameters.initialize_network:
|
|
|
|
if parameters.join_network or parameters.create_network:
|
|
|
|
print("Can't supply --join-network or --create-network with --initialize-network")
|
|
|
|
sys.exit(1)
|
|
|
|
if not parameters.chain_id:
|
|
|
|
print("--chain-id is required")
|
|
|
|
sys.exit(1)
|
2023-08-09 03:06:44 +00:00
|
|
|
# node_moniker must be supplied
|
|
|
|
if not parameters.node_moniker:
|
|
|
|
print("Error: --node-moniker is required")
|
|
|
|
sys.exit(1)
|
2023-08-08 19:03:10 +00:00
|
|
|
phase = SetupPhase.INITIALIZE
|
|
|
|
elif parameters.join_network:
|
|
|
|
if parameters.initialize_network or parameters.create_network:
|
|
|
|
print("Can't supply --initialize-network or --create-network with --join-network")
|
|
|
|
sys.exit(1)
|
|
|
|
phase = SetupPhase.JOIN
|
|
|
|
elif parameters.create_network:
|
|
|
|
if parameters.initialize_network or parameters.join_network:
|
|
|
|
print("Can't supply --initialize-network or --join-network with --create-network")
|
|
|
|
sys.exit(1)
|
|
|
|
phase = SetupPhase.CREATE
|
|
|
|
|
2023-08-09 14:17:30 +00:00
|
|
|
network_dir = Path(parameters.network_dir).absolute()
|
|
|
|
laconicd_home_path_in_container = "/laconicd-home"
|
|
|
|
mounts = [
|
|
|
|
VolumeMapping(network_dir, laconicd_home_path_in_container)
|
|
|
|
]
|
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
if phase == SetupPhase.INITIALIZE:
|
2023-08-09 14:17:30 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
# We want to create the directory so if it exists that's an error
|
|
|
|
if os.path.exists(network_dir):
|
|
|
|
print(f"Error: network directory {network_dir} already exists")
|
|
|
|
sys.exit(1)
|
2023-08-09 03:06:44 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
os.mkdir(network_dir)
|
2023-08-09 14:17:30 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
output, status = run_container_command(
|
2023-08-09 14:17:30 +00:00
|
|
|
command_context,
|
|
|
|
"laconicd", f"laconicd init {parameters.node_moniker} --home {laconicd_home_path_in_container} --chain-id {parameters.chain_id}", mounts)
|
2023-08-08 19:03:10 +00:00
|
|
|
print(f"Command output: {output}")
|
|
|
|
|
|
|
|
elif phase == SetupPhase.JOIN:
|
|
|
|
if not os.path.exists(network_dir):
|
|
|
|
print(f"Error: network directory {network_dir} doesn't exist")
|
|
|
|
sys.exit(1)
|
2023-08-09 03:06:44 +00:00
|
|
|
# Get the chain_id from the config file created in the INITIALIZE phase
|
2023-08-15 11:13:35 +00:00
|
|
|
chain_id = _get_chain_id_from_config(network_dir)
|
2023-08-09 14:17:30 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
output1, status1 = run_container_command(
|
2023-08-09 14:17:30 +00:00
|
|
|
command_context, "laconicd", f"laconicd keys add {parameters.key_name} --home {laconicd_home_path_in_container} --keyring-backend test", mounts)
|
2023-08-08 19:03:10 +00:00
|
|
|
print(f"Command output: {output1}")
|
|
|
|
output2, status2 = run_container_command(
|
|
|
|
command_context,
|
|
|
|
"laconicd",
|
2023-08-09 14:17:30 +00:00
|
|
|
f"laconicd add-genesis-account {parameters.key_name} 12900000000000000000000achk --home {laconicd_home_path_in_container} --keyring-backend test",
|
2023-08-08 19:03:10 +00:00
|
|
|
mounts)
|
2023-08-22 03:11:30 +00:00
|
|
|
print(f"Command output: {output2}")
|
2023-08-08 19:03:10 +00:00
|
|
|
output3, status3 = run_container_command(
|
|
|
|
command_context,
|
|
|
|
"laconicd",
|
2023-08-09 14:17:30 +00:00
|
|
|
f"laconicd gentx {parameters.key_name} 90000000000achk --home {laconicd_home_path_in_container} --chain-id {chain_id} --keyring-backend test",
|
2023-08-08 19:03:10 +00:00
|
|
|
mounts)
|
|
|
|
print(f"Command output: {output3}")
|
2023-08-22 03:11:30 +00:00
|
|
|
output4, status4 = run_container_command(
|
|
|
|
command_context,
|
|
|
|
"laconicd",
|
|
|
|
f"laconicd keys show {parameters.key_name} -a --home {laconicd_home_path_in_container} --keyring-backend test",
|
|
|
|
mounts)
|
|
|
|
print(f"Command output: {output4}")
|
2023-08-08 19:03:10 +00:00
|
|
|
|
|
|
|
elif phase == SetupPhase.CREATE:
|
|
|
|
if not os.path.exists(network_dir):
|
|
|
|
print(f"Error: network directory {network_dir} doesn't exist")
|
|
|
|
sys.exit(1)
|
2023-08-09 14:17:30 +00:00
|
|
|
|
2023-08-08 19:03:10 +00:00
|
|
|
output1, status1 = run_container_command(
|
2023-08-09 14:17:30 +00:00
|
|
|
command_context, "laconicd", f"laconicd collect-gentxs --home {laconicd_home_path_in_container}", mounts)
|
2023-08-22 03:11:30 +00:00
|
|
|
print(f"Command output: {output1}")
|
2023-08-08 19:03:10 +00:00
|
|
|
output2, status1 = run_container_command(
|
2023-08-09 14:17:30 +00:00
|
|
|
command_context, "laconicd", f"laconicd validate-genesis --home {laconicd_home_path_in_container}", mounts)
|
2023-08-08 19:03:10 +00:00
|
|
|
print(f"Command output: {output2}")
|
|
|
|
else:
|
|
|
|
print("Illegal parameters supplied")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
def create(command_context: DeployCommandContext):
|
|
|
|
print("Copy the network files here")
|
2023-07-24 02:54:05 +00:00
|
|
|
|
|
|
|
|
2023-07-30 04:38:46 +00:00
|
|
|
def init(command_context: DeployCommandContext):
|
2023-07-24 02:54:05 +00:00
|
|
|
print(init_help_text)
|
|
|
|
yaml = get_yaml()
|
|
|
|
return yaml.load(default_spec_file_content)
|
|
|
|
|
|
|
|
|
2023-07-30 04:38:46 +00:00
|
|
|
def get_state(command_context: DeployCommandContext):
|
2023-07-24 02:54:05 +00:00
|
|
|
print("Here we get state")
|
|
|
|
return State.CONFIGURED
|
|
|
|
|
2023-06-27 22:58:41 +00:00
|
|
|
|
2023-07-30 04:38:46 +00:00
|
|
|
def change_state(command_context: DeployCommandContext):
|
2023-07-24 02:54:05 +00:00
|
|
|
pass
|