mirror of
https://github.com/vvzvlad/vestasync.git
synced 2024-11-05 06:49:11 +03:00
add: test conn, multihosts, refactoring
This commit is contained in:
parent
c43559caed
commit
a3a08cd890
30
README.md
30
README.md
@ -44,7 +44,8 @@ pip install -r requirements.txt
|
||||
### install — установка на контроллер
|
||||
|
||||
Команда `install` выполняет подготовительные действия — устанавливает ПО, создает гит-репозитарий, устанавливает службы (подробнее в разделе "Службы").
|
||||
Эту команду надо выполнять, указывая в ```device_ip``` исходный контроллер (который будет стоять в проде инсталляции) перед началом эксплуатации (если выполнять ее еще до настройки, то бонусом получим сохранение конфигов и wb-rules в гите во время разработки и ПНР). Эта команда выполняется на контроллере один раз. При повторном запуске она перезапишет файлы скриптов и сервисов, этим можно пользоваться для обновления скриптов на существующих контроллерах, если вышла новая версия Vestasync.
|
||||
Эту команду надо выполнять, указывая в ```device_ip``` исходный контроллер (который будет стоять в проде инсталляции) перед началом эксплуатации (если выполнять ее еще до настройки, то бонусом получим сохранение конфигов и wb-rules в гите во время разработки и ПНР). Эта команда выполняется на контроллере один раз.
|
||||
|
||||
|
||||
Пример запуска (запускается на локальной машине, адрес контроллера указывается в ```device_ip```):
|
||||
|
||||
@ -55,13 +56,25 @@ pip install -r requirements.txt
|
||||
--gitea_address http://192.168.1.101:3001/
|
||||
--device_new_name WB2
|
||||
--gitea_token de8a2eaee0d2f27746157c2fd563815f932d671c`
|
||||
--user_cmd user_cmd.sh
|
||||
```
|
||||
|
||||
```--cmd install```: означает, что надо установить Vestasync на контроллер и подготовить его к созданию бекапа
|
||||
```--device_ip```: IP-адрес контроллера
|
||||
```--gitea_address```: адрес Gitea-сервера, куда будет отправлен бекап в виде "http://192.168.1.101:3001/"
|
||||
```--device_new_name```: имя контроллера, из которого вместе с SN будет сформировано название контроллера, которое запишется в хостнейм и будет служить именем репозитария с конфигами
|
||||
```--gitea_token```: токен для авторизации на Gitea-сервере (получается в интерфейсе)
|
||||
```--gitea_token```: токен для авторизации на Gitea-сервере (получается в интерфейсе Gitea)
|
||||
```--user_cmd```: файл sh с командами, которые надо выполняить на контроллере для его настройки под ваши задачи (указывать необязательно). В нем можно описать любые команды, которыми вам надо конфигурировать контроллер: например, установка ключа SSH, установка таймзоны и локали, и так далее. Пример файла — ```user_cmd.sh```:
|
||||
|
||||
```
|
||||
#!/usr/bin/env sh
|
||||
timedatectl set-timezone Asia/Krasnoyarsk
|
||||
localectl set-locale LANG=en_GB.UTF-8
|
||||
service ntp stop
|
||||
ntpdate pool.ntp.org
|
||||
service ntp start
|
||||
hwclock --systohc --localtime
|
||||
```
|
||||
|
||||
|
||||
### restore — восстановление из бекапа
|
||||
@ -117,7 +130,18 @@ reboot
|
||||
|
||||
### Пользовательские команды
|
||||
|
||||
В папке системы лежит файл "user_cmd.sh", внутри которого можно описать любые команды, которыми вам надо конфигурировать контроллер: например, установка ключа SSH, установка таймзоны и локали, и так далее. Если вы не хотите ничего устанавливать, оставьте его пустым.
|
||||
В папке системы лежит файл "user_cmd.sh", Если вы не хотите ничего устанавливать, оставьте его пустым.
|
||||
|
||||
### Обновление скриптов
|
||||
При повторном запуске команда ```install``` перезапишет файлы скриптов и сервисов для обновления скриптов на существующих контроллерах, если вышла новая версия Vestasync.
|
||||
В этом случае в ```--device_ip``` можно передать несколько IP-адресов:
|
||||
|
||||
```
|
||||
./vestasync.py --cmd install --device_ip 192.168.98.92 192.168.98.85 --gitea_address http://192.168.98.101:3001/ --device_new_name WB1 --gitea_token de8a2eaee0d2f27746157c2fd563815f932d670c
|
||||
```
|
||||
|
||||
Обратите внимание, что устанавливать Vestasync на несколько контроллеров лучше с помощью скрипта ниже, потому что при указании набора из нескольких адресов ```device_ip``` с командой ```install``` у них будет одинаковые имена хостов (```--device_new_name WB1```), отличающееся только серийным номером: WB1-AFYATAO7, WB1-A3TBJXLS и так далее.
|
||||
|
||||
|
||||
### Множественный запуск
|
||||
|
||||
|
197
vestasync.py
197
vestasync.py
@ -9,6 +9,7 @@ import re
|
||||
import sys
|
||||
import datetime
|
||||
import json
|
||||
import socket
|
||||
|
||||
|
||||
device_user = "root"
|
||||
@ -28,8 +29,8 @@ else:
|
||||
main_parser.add_argument('--device_new_name', help='Device new name', required=True)
|
||||
main_parser.add_argument('--gitea_address', help='Gitea address string', required=True)
|
||||
main_parser.add_argument('--gitea_token', help='Gitea token', required=True)
|
||||
main_parser.add_argument('--device_ip', help='Device IP', required=True)
|
||||
|
||||
main_parser.add_argument('--device_ip', help='Device IP(s)', required=True, nargs='+', type=str)
|
||||
main_parser.add_argument('--user_cmd', help='User commands file')
|
||||
|
||||
args = main_parser.parse_known_args()
|
||||
args = args[0]
|
||||
@ -53,6 +54,8 @@ def get_short_sn(c):
|
||||
|
||||
def set_hostname(c):
|
||||
c.run(f'hostnamectl set-hostname {args.device_new_name}-{device_short_sn}')
|
||||
hostname = c.run('hostname', hide=True).stdout.strip()
|
||||
return hostname
|
||||
|
||||
def save_hostname(c):
|
||||
c.run(f'echo $(hostname) > /mnt/data/etc/vestasync/hostname')
|
||||
@ -103,53 +106,75 @@ def copy_wb_rule(c):
|
||||
c.put("./files/vestasync.js", wb_rule_path)
|
||||
|
||||
def create_automac_systemd(c):
|
||||
apply_macs_script_path = "/usr/local/bin/apply_macs.sh"
|
||||
c.run(f"rm {apply_macs_script_path} || true")
|
||||
c.put("./files/apply_macs.sh", apply_macs_script_path)
|
||||
c.run(f"chmod +x {apply_macs_script_path}")
|
||||
#disable
|
||||
for service in ['apply_macs.service']:
|
||||
c.run(f'systemctl disable {service} || true')
|
||||
|
||||
apply_macs_service_path = "/etc/systemd/system/apply_macs.service"
|
||||
c.run(f"rm {apply_macs_service_path} || true")
|
||||
c.put("./files/apply_macs.service", apply_macs_service_path)
|
||||
file_paths = { #local path: remote path
|
||||
'./files/apply_macs.sh': '/usr/local/bin/apply_macs.sh',
|
||||
'./files/apply_macs.service': '/etc/systemd/system/apply_macs.service',
|
||||
}
|
||||
|
||||
c.run("systemctl disable apply_macs.service || true")
|
||||
for local_path, remote_path in file_paths.items():
|
||||
c.run(f"rm {remote_path} || true")
|
||||
c.put(local_path, remote_path)
|
||||
c.run(f"chmod +x {remote_path}")
|
||||
|
||||
#reload
|
||||
c.run("systemctl daemon-reload")
|
||||
c.run("systemctl enable apply_macs.service")
|
||||
|
||||
#enable and start
|
||||
for service in ['apply_macs.service']:
|
||||
c.run(f'systemctl enable {service}')
|
||||
c.run(f'systemctl start {service}')
|
||||
|
||||
|
||||
#check statuses
|
||||
for service in ['apply_macs.service']:
|
||||
active = c.run(f'systemctl is-active {service} || true', hide=True).stdout.strip()
|
||||
enabled = c.run(f'systemctl is-enabled {service} || true', hide=True).stdout.strip()
|
||||
print(f"{service}: {active}, {enabled}")
|
||||
|
||||
|
||||
|
||||
|
||||
def create_autogit_systemd(c):
|
||||
pushgit_script_path = "/usr/local/bin/pushgit.sh"
|
||||
c.run(f"rm {pushgit_script_path} || true")
|
||||
c.put("./files/pushgit.sh", pushgit_script_path)
|
||||
c.run(f"chmod +x {pushgit_script_path}")
|
||||
|
||||
pushgit_inotify_script_path = "/usr/local/bin/pushgit_inotify.sh"
|
||||
c.run(f"rm {pushgit_inotify_script_path} || true")
|
||||
c.put("./files/pushgit.sh", pushgit_inotify_script_path)
|
||||
c.run(f"chmod +x {pushgit_inotify_script_path}")
|
||||
|
||||
pushgit_inotify_service_path = "/etc/systemd/system/pushgit_inotify.service"
|
||||
c.run(f"rm {pushgit_inotify_service_path} || true")
|
||||
c.put("./files/pushgit_inotify.service", pushgit_inotify_service_path)
|
||||
c.run(f"chmod +x {pushgit_inotify_service_path}")
|
||||
|
||||
pushgit_service_path = "/etc/systemd/system/pushgit.service"
|
||||
c.run(f"rm {pushgit_service_path} || true")
|
||||
c.put("./files/pushgit.service", pushgit_service_path)
|
||||
c.run(f"chmod +x {pushgit_service_path}")
|
||||
|
||||
pushgit_timer_path = "/etc/systemd/system/pushgit.timer"
|
||||
c.run(f"rm {pushgit_timer_path} || true")
|
||||
c.put("./files/pushgit.timer", pushgit_timer_path)
|
||||
c.run(f"chmod +x {pushgit_timer_path}")
|
||||
#disable
|
||||
for service in ['pushgit.timer', 'pushgit_inotify.service']:
|
||||
c.run(f'systemctl disable {service} || true')
|
||||
|
||||
|
||||
c.run("systemctl disable pushgit.timer || true")
|
||||
c.run("systemctl disable pushgit_inotify.service || true")
|
||||
#delete old files, copy new files, chmod +x
|
||||
file_paths = { #local path: remote path
|
||||
'./files/pushgit.sh': '/usr/local/bin/pushgit.sh',
|
||||
'./files/pushgit_inotify.sh': '/usr/local/bin/pushgit_inotify.sh',
|
||||
'./files/pushgit_inotify.service': '/etc/systemd/system/pushgit_inotify.service',
|
||||
'./files/pushgit.service': '/etc/systemd/system/pushgit.service',
|
||||
'./files/pushgit.timer': '/etc/systemd/system/pushgit.timer'
|
||||
}
|
||||
|
||||
for local_path, remote_path in file_paths.items():
|
||||
c.run(f"rm {remote_path} || true")
|
||||
c.put(local_path, remote_path)
|
||||
c.run(f"chmod +x {remote_path}")
|
||||
|
||||
#reload
|
||||
c.run("systemctl daemon-reload")
|
||||
c.run("systemctl enable pushgit.timer")
|
||||
c.run("systemctl start pushgit.timer")
|
||||
c.run("systemctl enable pushgit_inotify.service")
|
||||
c.run("systemctl start pushgit_inotify.service")
|
||||
|
||||
#enable and start
|
||||
for service in ['pushgit.timer', 'pushgit_inotify.service']:
|
||||
c.run(f'systemctl enable {service}')
|
||||
c.run(f'systemctl start {service}')
|
||||
|
||||
|
||||
#check statuses
|
||||
for service in ['pushgit.timer', 'pushgit_inotify.service', 'pushgit.service']:
|
||||
active = c.run(f'systemctl is-active {service} || true', hide=True).stdout.strip()
|
||||
enabled = c.run(f'systemctl is-enabled {service} || true', hide=True).stdout.strip()
|
||||
print(f"{service}: {active}, {enabled}")
|
||||
|
||||
|
||||
|
||||
|
||||
def reboot(c):
|
||||
c.run("reboot > /dev/null 2>&1 || true")
|
||||
@ -219,42 +244,66 @@ def check_vestasync_installed(c):
|
||||
result = c.run(f"test -d {vestasync_path}", warn=True)
|
||||
return result.ok
|
||||
|
||||
def device_install():
|
||||
with Connection(host=args.device_ip, user=device_user, connect_kwargs={"password": "wirenboard"}) as c:
|
||||
if not check_vestasync_installed(c):
|
||||
prepare_packages_wb(c)
|
||||
configure_git(c)
|
||||
get_short_sn(c)
|
||||
set_hostname(c)
|
||||
create_repo(c)
|
||||
init_repo(c)
|
||||
ppush_the_repo(c)
|
||||
save_mac_in_cfg(c)
|
||||
save_hostname(c)
|
||||
copy_wb_rule(c)
|
||||
ppush_the_repo(c)
|
||||
create_automac_systemd(c)
|
||||
create_autogit_systemd(c)
|
||||
run_user_cmd(c)
|
||||
reboot(c)
|
||||
else:
|
||||
print("Found vestasync! Update...")
|
||||
copy_wb_rule(c)
|
||||
create_automac_systemd(c)
|
||||
create_autogit_systemd(c)
|
||||
def device_install(c):
|
||||
print("Found vestasync! Update...")
|
||||
copy_wb_rule(c)
|
||||
create_automac_systemd(c)
|
||||
create_autogit_systemd(c)
|
||||
print("Update vestasync complete\n")
|
||||
|
||||
def device_update(c):
|
||||
print("Not found vestasync! Install...")
|
||||
prepare_packages_wb(c)
|
||||
configure_git(c)
|
||||
get_short_sn(c)
|
||||
set_hostname(c)
|
||||
create_repo(c)
|
||||
init_repo(c)
|
||||
ppush_the_repo(c)
|
||||
save_mac_in_cfg(c)
|
||||
hostname = save_hostname(c)
|
||||
copy_wb_rule(c)
|
||||
ppush_the_repo(c)
|
||||
create_automac_systemd(c)
|
||||
create_autogit_systemd(c)
|
||||
run_user_cmd(c)
|
||||
reboot(c)
|
||||
print(f"Install vestasync complete (hostname {hostname}), reboot target device\n")
|
||||
|
||||
def device_install_or_update():
|
||||
print(f"Install/update command on host(s) {', '.join(args.device_ip)}")
|
||||
for device_ip in args.device_ip:
|
||||
with Connection(host=device_ip, user=device_user, connect_kwargs={"password": "wirenboard"}) as c:
|
||||
print(f"\nConnect to {device_ip} as {device_user}..")
|
||||
try:
|
||||
if not check_vestasync_installed(c):
|
||||
device_update(c)
|
||||
else:
|
||||
device_install(c)
|
||||
except socket.timeout:
|
||||
print(f"Failed to connect to the host {device_ip}")
|
||||
|
||||
|
||||
def device_restore():
|
||||
with Connection(host=args.device_ip, user=device_user) as c:
|
||||
#prepare_packages_wb(c)
|
||||
#configure_git(c)
|
||||
#git_clone(c)
|
||||
#copy_etc(c)
|
||||
#restore_hostname(c)
|
||||
#ppush_the_repo(c)
|
||||
for device_ip in args.device_ip:
|
||||
with Connection(host=device_ip, user=device_user) as c:
|
||||
print(f"\nConnect to {device_ip} as {device_user}..")
|
||||
try:
|
||||
if check_vestasync_installed(c):
|
||||
prepare_packages_wb(c)
|
||||
configure_git(c)
|
||||
git_clone(c)
|
||||
copy_etc(c)
|
||||
restore_hostname(c)
|
||||
ppush_the_repo(c)
|
||||
create_autogit_systemd(c)
|
||||
create_automac_systemd(c)
|
||||
except socket.timeout:
|
||||
print(f"Failed to connect to the host {device_ip}")
|
||||
|
||||
|
||||
|
||||
|
||||
create_autogit_systemd(c)
|
||||
create_automac_systemd(c)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -266,7 +315,7 @@ if __name__ == '__main__':
|
||||
exit(1)
|
||||
|
||||
if cmd_args.cmd == "install":
|
||||
device_install()
|
||||
device_install_or_update()
|
||||
if cmd_args.cmd == "restore":
|
||||
device_restore()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user