diff --git a/docker-compose.test.yml b/docker-compose.test.yml index abdd40d..d3c4c37 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -20,6 +20,8 @@ services: volumes: - sync1config:/config - etcd + environment: + - SYNCTHING_HOSTNAME=sync1 networks: - syncnet @@ -42,6 +44,8 @@ services: - etcd volumes: - sync2config:/config + environment: + - SYNCTHING_HOSTNAME=sync2 networks: - syncnet diff --git a/syncthing_monitor/__main__.py b/syncthing_monitor/__main__.py index 61fe53e..6c39d01 100644 --- a/syncthing_monitor/__main__.py +++ b/syncthing_monitor/__main__.py @@ -1,3 +1,6 @@ +import os +import time + import syncthing_monitor.config_xml as xml from .etcd_client import EtcdClient from .syncthing_client import SyncthingClient @@ -16,12 +19,27 @@ def loop(gui_port="8384", host="sync"): my_device_id = syncthing.get_my_device_id() print("Found Device ID: {0}".format(my_device_id)) - etcd = EtcdClient('etcd') - etcd.append_device_id(my_device_id) - device_ids = etcd.get_device_list() + my_syncthing_hostname = os.getenv('SYNCTHING_HOSTNAME') - syncthing.add_devices(device_ids) - syncthing.print_config() + etcd = EtcdClient('etcd') + updater = Updater(etcd, syncthing) + etcd.register_device_update_handler(updater.update_devices) + etcd.append_device_id(my_device_id, my_syncthing_hostname) + + while True: + time.sleep(1) + + +class Updater: + def __init__(self, etcd, syncthing): + self.etcd = etcd + self.syncthing = syncthing + + # noinspection PyUnusedLocal + def update_devices(self, event): + device_list = self.etcd.get_device_list() + self.syncthing.add_devices(device_list) + self.syncthing.print_config() if __name__ == "__main__": diff --git a/syncthing_monitor/etcd_client.py b/syncthing_monitor/etcd_client.py index 0cb14ba..6035cb4 100644 --- a/syncthing_monitor/etcd_client.py +++ b/syncthing_monitor/etcd_client.py @@ -12,18 +12,25 @@ class EtcdClient: self.etcd = etcd3.client(host=host, port=port) def load_cluster_info(self): - raw_value, meta = self.etcd.get(CLUSTER_INFO_KEY) + raw_value = self.etcd.get(CLUSTER_INFO_KEY)[0] if raw_value is None: return {'devices': []} return json.loads(raw_value) @retry - def append_device_id(self, device_id): + def append_device_id(self, device_id, hostname): with self.etcd.lock('syncthing_monitor'): cluster_info = self.load_cluster_info() - if not any(device_id in element for element in cluster_info['devices']): - cluster_info['devices'].append(device_id) + if any(device_id in device['id'] for device in cluster_info['devices']): + return + + new_device = { + 'id': device_id, + 'hostname': hostname + } + + cluster_info['devices'].append(new_device) print("Updating etcd value for '{0}': {1}".format(CLUSTER_INFO_KEY, json.dumps(cluster_info))) self.etcd.put(CLUSTER_INFO_KEY, json.dumps(cluster_info)) @@ -33,3 +40,6 @@ class EtcdClient: device_list = self.load_cluster_info()['devices'] print("Obtained device_list devices from etcd: {0}".format(json.dumps(device_list))) return device_list + + def register_device_update_handler(self, device_update_handler): + self.etcd.add_watch_callback(CLUSTER_INFO_KEY, device_update_handler) diff --git a/syncthing_monitor/syncthing_client.py b/syncthing_monitor/syncthing_client.py index 0874c1a..b29721c 100644 --- a/syncthing_monitor/syncthing_client.py +++ b/syncthing_monitor/syncthing_client.py @@ -19,17 +19,17 @@ class SyncthingClient: response = requests.get(self.make_url("/rest/system/status"), headers=self.headers) return json.loads(response.content)["myID"] - def add_devices(self, device_ids): - for device_id in device_ids: - self.add_device(device_id) + def add_devices(self, device_list): + for device in device_list: + self.add_device(device) - def add_device(self, device_id): + def add_device(self, device): post_data = { - "deviceID": device_id, - "name": "Laptop", + "deviceID": device['id'], + "name": device['hostname'], "addresses": [ "dynamic", - "tcp://192.168.1.2:22000" + "tcp://{0}:22000".format(device['hostname']) ], "compression": "metadata", "certName": "", @@ -48,7 +48,7 @@ class SyncthingClient: response = requests.post(self.make_url("/rest/config/devices"), headers=self.headers, data=json.dumps(post_data)) - print("Attempt to add device {0} to syncthing: {1}".format(device_id, response.content)) + print("Attempt to add device {0} to syncthing: {1}".format(device, response.content)) @retry def print_config(self):