import os import sys import time import syncthing_monitor.config_xml as xml from .etcd_client import EtcdClient from .syncthing_client import SyncthingClient SHARED_FOLDER_ID = "data" SHARED_FOLDER_LABEL = "syncthing_monitor_data" SYNCTHING_CONFIG_XML_PATH = '/config/config.xml' SYNCTHING_GUI_PORT = 8384 ETCD_PORT = 2379 ETCD_KEY = '/syncthing_monitor/cluster_info' def main(): syncthing_mon = SyncthingMonitor(os.getenv('SYNCTHING_NODE_NAME', 'sync'), os.getenv('SYNCTHING_PUBLISH_ADDRESS', 'tcp4://sync'), os.getenv('SYNCTHING_DATA_PATH', '/data'), os.getenv('SYNCTHING_CONFIG_XML_PATH', SYNCTHING_CONFIG_XML_PATH), os.getenv('SYNCTHING_LOCAL_HOSTNAME', 'sync'), os.getenv('SYNCTHING_GUI_PORT', SYNCTHING_GUI_PORT), os.getenv('ETCD_HOSTNAME', 'etcd'), os.getenv('ETCD_PORT', ETCD_PORT), os.getenv('ETCD_KEY', ETCD_KEY)) syncthing_mon.start() class SyncthingMonitor: def __init__(self, syncthing_node_name, syncthing_publish_address, syncthing_data_path, syncthing_config_xml_path, syncthing_local_hostname, syncthing_gui_port, etcd_hostname, etcd_port, etcd_key): self.syncthing_node_name = syncthing_node_name self.syncthing_publish_address = syncthing_publish_address self.syncthing_data_path = syncthing_data_path self.my_device_id = None self.syncthing = None self.etcd = EtcdClient(etcd_hostname, etcd_port, etcd_key) self.syncthing_gui_port = syncthing_gui_port self.syncthing_local_hostname = syncthing_local_hostname self.syncthing_config_xml_path = syncthing_config_xml_path def initialize_syncthing(self): api_key = xml.parse_api_key(self.syncthing_config_xml_path) print("Found API Key: {0}".format(api_key)) print("Configuring Syncthing to listen on 0.0.0.0...", flush=True) xml.set_listen_ip_to_any(self.syncthing_config_xml_path, self.syncthing_config_xml_path, self.syncthing_gui_port) self.syncthing = SyncthingClient(api_key, self.syncthing_local_hostname, self.syncthing_gui_port) def start(self): self.initialize_syncthing() self.my_device_id = self.syncthing.get_my_device_id() print("Found My Device ID: {0}".format(self.my_device_id), flush=True) print("Disabling global/local discovery/relay...", flush=True) self.syncthing.disable_announce_discovery_and_relay() self.syncthing.sync_config() print("Registering etcd update callback...", flush=True) self.etcd.register_device_update_handler(self.update_devices) print("Attempting to add this device to etcd...", flush=True) self.etcd.add_device_to_cluster(self.my_device_id, self.syncthing_node_name, self.syncthing_publish_address) print("Added this device to cluster with publish address: {0}".format(self.syncthing_publish_address), flush=True) self.update_devices(None) print("Entering loop...", flush=True) self.loop() @staticmethod def loop(): while True: sys.stdout.flush() time.sleep(1) # noinspection PyUnusedLocal def update_devices(self, event): print("*** Updating syncthing based on change to cluster info ***", flush=True) print("Obtaining updated device list...", flush=True) device_list = self.etcd.get_device_list() print("Adding new devices to syncthing...", flush=True) self.syncthing.add_devices(device_list) print("Updating shared folder with new devices...", flush=True) self.syncthing.create_shared_folder(SHARED_FOLDER_ID, SHARED_FOLDER_LABEL, self.syncthing_data_path, device_list) self.syncthing.sync_config() self.syncthing.print_config() print("*** Update complete ***", flush=True) if __name__ == "__main__": main()