Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote controller #406

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Setting:
'ChatId': Setting('alert-bot', None, 'Alerting Telegram chat id'),
'auto_backup': Setting('validator', None, 'Make validator backup every election'),
'auto_backup_path': Setting('validator', '/tmp/mytoncore/auto_backups/', 'Path to store auto-backups'),
'onlyNode': Setting(None, None, 'MyTonCtrl will work only for collecting validator telemetry (if `sendTelemetry` is True), without participating in Elections and etc.')
}


Expand Down
2 changes: 1 addition & 1 deletion modules/alert_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def init(self):
from modules.validator import ValidatorModule
self.validator_module = ValidatorModule(self.ton, self.local)
self.hostname = get_hostname()
self.ip = self.ton.get_validator_engine_ip()
self.ip = self.ton.get_node_ip()
self.set_global_vars()
self.inited = True

Expand Down
16 changes: 12 additions & 4 deletions modules/backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ def create_tmp_ton_dir(self):
self.create_keyring(dir_name_db)
return dir_name

@staticmethod
def run_create_backup(args):
backup_script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/create_backup.sh')
return subprocess.run(["bash", backup_script_path] + args, timeout=5)

def create_backup(self, args):
if len(args) > 1:
color_print("{red}Bad args. Usage:{endc} create_backup [filename]")
Expand All @@ -35,8 +40,7 @@ def create_backup(self, args):
command_args = ["-m", self.ton.local.buffer.my_work_dir, "-t", tmp_dir]
if len(args) == 1:
command_args += ["-d", args[0]]
backup_script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/create_backup.sh')
process = subprocess.run(["bash", backup_script_path] + command_args, timeout=5)
process = self.run_create_backup(command_args)

if process.returncode == 0:
color_print("create_backup - {green}OK{endc}")
Expand All @@ -46,6 +50,11 @@ def create_backup(self, args):
return process.returncode
# end define

@staticmethod
def run_restore_backup(args):
restore_script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/restore_backup.sh')
return run_as_root(["bash", restore_script_path] + args)

def restore_backup(self, args):
if len(args) == 0 or len(args) > 2:
color_print("{red}Bad args. Usage:{endc} restore_backup <filename> [-y]")
Expand All @@ -67,8 +76,7 @@ def restore_backup(self, args):
ip = str(ip2int(get_own_ip()))
command_args = ["-m", self.ton.local.buffer.my_work_dir, "-n", args[0], "-i", ip]

restore_script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/restore_backup.sh')
if run_as_root(["bash", restore_script_path] + command_args) == 0:
if self.run_restore_backup(command_args) == 0:
color_print("restore_backup - {green}OK{endc}")
self.local.exit()
else:
Expand Down
10 changes: 7 additions & 3 deletions mytoncore/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,14 @@ def General(local):
# scanner.Run()

# Start threads
local.start_cycle(Elections, sec=600, args=(local, ton, ))
local.start_cycle(Statistics, sec=10, args=(local, ))
local.start_cycle(Telemetry, sec=60, args=(local, ton, ))
local.start_cycle(OverlayTelemetry, sec=7200, args=(local, ton, ))
if local.db.get("onlyNode"): # mytoncore service works only for telemetry
thr_sleep()
return

local.start_cycle(Elections, sec=600, args=(local, ton, ))
local.start_cycle(Offers, sec=600, args=(local, ton, ))
local.start_cycle(save_past_events, sec=300, args=(local, ton, ))

Expand All @@ -562,8 +568,6 @@ def General(local):
local.start_cycle(Complaints, sec=t, args=(local, ton, ))
local.start_cycle(Slashing, sec=t, args=(local, ton, ))

local.start_cycle(Telemetry, sec=60, args=(local, ton, ))
local.start_cycle(OverlayTelemetry, sec=7200, args=(local, ton, ))
local.start_cycle(ScanLiteServers, sec=60, args=(local, ton,))

from modules.custom_overlays import CustomOverlayModule
Expand Down
5 changes: 4 additions & 1 deletion mytoncore/mytoncore.py
Original file line number Diff line number Diff line change
Expand Up @@ -3820,13 +3820,16 @@ def GetNetworkName(self):
return "unknown"
#end define

def get_validator_engine_ip(self):
def get_node_ip(self):
try:
config = self.GetValidatorConfig()
return int2ip(config['addrs'][0]['ip'])
except:
return None

def get_validator_engine_ip(self):
return self.validatorConsole.addr.split(':')[0]

def GetFunctionBuffer(self, name, timeout=10):
timestamp = get_timestamp()
buff = self.local.buffer.get(name)
Expand Down
8 changes: 7 additions & 1 deletion mytonctrl/mytonctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,11 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency,
validatorVersion_text = local.translate("local_status_version_validator").format(validatorGitHash_text, validatorGitBranch_text)

color_print(local.translate("local_status_head"))
node_ip = ton.get_validator_engine_ip()
is_node_remote = node_ip != '127.0.0.1'
if is_node_remote:
nodeIpAddr_text = local.translate("node_ip_address").format(node_ip)
color_print(nodeIpAddr_text)
if ton.using_validator():
print(validatorIndex_text)
# print(validatorEfficiency_text)
Expand All @@ -776,7 +781,8 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency,

print(disksLoad_text)
print(mytoncoreStatus_text)
print(validatorStatus_text)
if not is_node_remote:
print(validatorStatus_text)
print(validator_out_of_sync_text)
print(validator_out_of_ser_text)
print(dbStatus_text)
Expand Down
5 changes: 5 additions & 0 deletions mytonctrl/resources/translate.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@
"ru": "{cyan}===[ Статус ноды ]==={endc}",
"zh_TW": "{cyan}===[ 节点狀態 ]==={endc}"
},
"node_ip_address": {
"en": "Node IP address: {{bold}}{0}{{endc}}",
"ru": "IP адрес Ноды: {{bold}}{0}{{endc}}",
"zh_TW": "節點 IP 地址: {{bold}}{0}{{endc}}"
},
"local_status_validator_index": {
"en": "Validator index: {0}",
"ru": "Индекс валидатора: {0}",
Expand Down
23 changes: 17 additions & 6 deletions mytonctrl/scripts/restore_backup.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
name="backup.tar.gz"
mtc_dir="$HOME/.local/share/mytoncore"
ip=0
user=$(logname)
# Get arguments
while getopts n:m:i: flag
while getopts n:m:i:u: flag
do
case "${flag}" in
n) name=${OPTARG};;
m) mtc_dir=${OPTARG};;
i) ip=${OPTARG};;
u) user=${OPTARG};;
*)
echo "Flag -${flag} is not recognized. Aborting"
exit 1 ;;
Expand Down Expand Up @@ -38,19 +40,28 @@ if [ ! -d ${tmp_dir}/db ]; then
fi

rm -rf /var/ton-work/db/keyring
cp -rf ${tmp_dir}/db /var/ton-work
cp -rf ${tmp_dir}/keys /var/ton-work
cp -rfT ${tmp_dir}/mytoncore $mtc_dir

chown -R $user:$user ${tmp_dir}/mytoncore
chown -R $user:$user ${tmp_dir}/keys

cp -rfp ${tmp_dir}/db /var/ton-work
cp -rfp ${tmp_dir}/keys /var/ton-work
cp -rfpT ${tmp_dir}/mytoncore $mtc_dir

chown -R validator:validator /var/ton-work/db/keyring

echo -e "${COLOR}[2/4]${ENDC} Extracted files from archive"

rm -r /var/ton-work/db/dht-*

python3 -c "import json;path='/var/ton-work/db/config.json';f=open(path);d=json.load(f);f.close();d['addrs'][0]['ip']=int($ip);f=open(path, 'w');f.write(json.dumps(d, indent=4));f.close()"
if [ $ip -ne 0 ]; then
echo "Replacing IP in node config"
python3 -c "import json;path='/var/ton-work/db/config.json';f=open(path);d=json.load(f);f.close();d['addrs'][0]['ip']=int($ip);f=open(path, 'w');f.write(json.dumps(d, indent=4));f.close()"
else
echo "IP is not provided, skipping IP replacement"
fi

echo -e "${COLOR}[3/4]${ENDC} Deleted DHT files, replaced IP in node config"
echo -e "${COLOR}[3/4]${ENDC} Deleted DHT files"

systemctl start validator
systemctl start mytoncore
Expand Down
2 changes: 2 additions & 0 deletions mytoninstaller/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def backup_config(local, config_path):


def BackupVconfig(local):
if local.buffer.only_mtc:
return
local.add_log("Backup validator config file 'config.json' to 'config.json.backup'", "debug")
vconfig_path = local.buffer.vconfig_path
backupPath = vconfig_path + ".backup"
Expand Down
15 changes: 14 additions & 1 deletion mytoninstaller/mytoninstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
enable_ls_proxy,
enable_ton_storage,
enable_ton_storage_provider,
EnableMode
EnableMode, ConfigureFromBackup, ConfigureOnlyNode
)
from mytoninstaller.config import (
CreateLocalConfig,
Expand Down Expand Up @@ -276,6 +276,17 @@ def General(local, console):
mx = sys.argv.index("-m")
mode = sys.argv[mx+1]
local.buffer.mode = mode
if "--only-mtc" in sys.argv:
ox = sys.argv.index("--only-mtc")
local.buffer.only_mtc = str2bool(sys.argv[ox+1])
if "--only-node" in sys.argv:
ox = sys.argv.index("--only-node")
local.buffer.only_node = str2bool(sys.argv[ox+1])
if "--backup" in sys.argv:
bx = sys.argv.index("--backup")
backup = sys.argv[bx+1]
if backup != "none":
local.buffer.backup = backup
#end if

FirstMytoncoreSettings(local)
Expand All @@ -286,6 +297,8 @@ def General(local, console):
BackupMconfig(local)
CreateSymlinks(local)
EnableMode(local)
ConfigureFromBackup(local)
ConfigureOnlyNode(local)
#end define


Expand Down
73 changes: 71 additions & 2 deletions mytoninstaller/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
run_as_root,
color_print,
ip2int,
Dict
Dict, int2ip
)
from mytoninstaller.utils import StartValidator, StartMytoncore, start_service, stop_service, get_ed25519_pubkey
from mytoninstaller.config import SetConfig, GetConfig, get_own_ip, backup_config
from mytoncore.utils import hex2b64


def FirstNodeSettings(local):
if local.buffer.only_mtc:
return

local.add_log("start FirstNodeSettings fuction", "debug")

# Создать переменные
Expand Down Expand Up @@ -198,6 +201,8 @@ def FirstMytoncoreSettings(local):
#end define

def EnableValidatorConsole(local):
if local.buffer.only_mtc:
return
local.add_log("start EnableValidatorConsole function", "debug")

# Create variables
Expand Down Expand Up @@ -300,6 +305,9 @@ def EnableValidatorConsole(local):
#end define

def EnableLiteServer(local):
if local.buffer.only_mtc:
return

local.add_log("start EnableLiteServer function", "debug")

# Create variables
Expand Down Expand Up @@ -906,9 +914,70 @@ def CreateSymlinks(local):

def EnableMode(local):
args = ["python3", "-m", "mytoncore", "-e"]
if local.buffer.mode:
if local.buffer.mode and local.buffer.mode != "none":
args.append("enable_mode_" + local.buffer.mode)
else:
return
args = ["su", "-l", local.buffer.user, "-c", ' '.join(args)]
subprocess.run(args)


def set_external_ip(local, ip):
mconfig_path = local.buffer.mconfig_path

mconfig = GetConfig(path=mconfig_path)

mconfig.liteClient.liteServer.ip = ip
mconfig.validatorConsole.addr = f'{ip}:{mconfig.validatorConsole.addr.split(":")[1]}'

# write mconfig
local.add_log("write mconfig", "debug")
SetConfig(path=mconfig_path, data=mconfig)


def ConfigureFromBackup(local):
if not local.buffer.backup:
return
from modules.backups import BackupModule
mconfig_path = local.buffer.mconfig_path
mconfig_dir = get_dir_from_path(mconfig_path)
local.add_log("start ConfigureFromBackup function", "info")
backup_file = local.buffer.backup

os.makedirs(local.buffer.ton_work_dir, exist_ok=True)
if not local.buffer.only_mtc:
ip = str(ip2int(get_own_ip()))
BackupModule.run_restore_backup(["-m", mconfig_dir, "-n", backup_file, "-i", ip])

if local.buffer.only_mtc:
BackupModule.run_restore_backup(["-m", mconfig_dir, "-n", backup_file])
local.add_log("Installing only mtc", "info")
vconfig_path = local.buffer.vconfig_path
vconfig = GetConfig(path=vconfig_path)
try:
node_ip = int2ip(vconfig['addrs'][0]['ip'])
except:
local.add_log("Can't get ip from validator", "error")
return
set_external_ip(local, node_ip)


def ConfigureOnlyNode(local):
if not local.buffer.only_node:
return
from modules.backups import BackupModule
mconfig_path = local.buffer.mconfig_path
mconfig_dir = get_dir_from_path(mconfig_path)
local.add_log("start ConfigureOnlyNode function", "info")

process = BackupModule.run_create_backup(["-m", mconfig_dir, ])
if process.returncode != 0:
local.add_log("Backup creation failed", "error")
return
local.add_log("Backup successfully created. Use this file on the controller server with `--only-mtc` flag on installation.", "info")

mconfig = GetConfig(path=mconfig_path)
mconfig.onlyNode = True
SetConfig(path=mconfig_path, data=mconfig)

start_service(local, 'mytoncore')
Loading