mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Add interfaces selection for mDNS broadcast
- System setting added - Loop through list of interfaces
This commit is contained in:
parent
99390f2313
commit
654690b427
3 changed files with 65 additions and 43 deletions
|
@ -19,26 +19,23 @@ from typing import List
|
||||||
sys.path.insert(0, "/usr/lib/moulinette/")
|
sys.path.insert(0, "/usr/lib/moulinette/")
|
||||||
from yunohost.domain import domain_list
|
from yunohost.domain import domain_list
|
||||||
from yunohost.utils.network import get_network_interfaces
|
from yunohost.utils.network import get_network_interfaces
|
||||||
|
from yunohost.settings import settings_get
|
||||||
|
from moulinette import m18n
|
||||||
|
from moulinette.interfaces.cli import get_locale
|
||||||
|
|
||||||
from zeroconf import IPVersion
|
|
||||||
from zeroconf.asyncio import AsyncServiceInfo, AsyncZeroconf
|
from zeroconf.asyncio import AsyncServiceInfo, AsyncZeroconf
|
||||||
|
|
||||||
# TODO: Remove traceback beautification
|
|
||||||
from rich.traceback import install
|
|
||||||
install(show_locals=True)
|
|
||||||
|
|
||||||
async def register_services(infos: List[AsyncServiceInfo]) -> None:
|
async def register_services(aiozc: AsyncZeroconf, infos: List[AsyncServiceInfo]) -> None:
|
||||||
tasks = [aiozc.async_register_service(info) for info in infos]
|
tasks = [aiozc.async_register_service(info) for info in infos]
|
||||||
background_tasks = await asyncio.gather(*tasks)
|
background_tasks = await asyncio.gather(*tasks)
|
||||||
await asyncio.gather(*background_tasks)
|
await asyncio.gather(*background_tasks)
|
||||||
|
|
||||||
|
async def unregister_services(aiozc: AsyncZeroconf, infos: List[AsyncServiceInfo]) -> None:
|
||||||
async def unregister_services(infos: List[AsyncServiceInfo]) -> None:
|
|
||||||
tasks = [aiozc.async_unregister_service(info) for info in infos]
|
tasks = [aiozc.async_unregister_service(info) for info in infos]
|
||||||
background_tasks = await asyncio.gather(*tasks)
|
background_tasks = await asyncio.gather(*tasks)
|
||||||
await asyncio.gather(*background_tasks)
|
await asyncio.gather(*background_tasks)
|
||||||
|
|
||||||
|
|
||||||
async def close_aiozc(aiozc: AsyncZeroconf) -> None:
|
async def close_aiozc(aiozc: AsyncZeroconf) -> None:
|
||||||
await aiozc.async_close()
|
await aiozc.async_close()
|
||||||
|
|
||||||
|
@ -46,22 +43,6 @@ async def close_aiozc(aiozc: AsyncZeroconf) -> None:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
local_domains = [ d for d in domain_list()['domains'] if d.endswith('.local') ]
|
|
||||||
|
|
||||||
# TODO: Create setting to list interfaces
|
|
||||||
wanted_interfaces = [ 'zt3jnskpna' ]
|
|
||||||
interfaces = get_network_interfaces()
|
|
||||||
ips = []
|
|
||||||
for i in wanted_interfaces:
|
|
||||||
try:
|
|
||||||
ips.append(socket.inet_pton(socket.AF_INET, interfaces[i]['ipv4'].split('/')[0]))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
ips.append(socket.inet_pton(socket.AF_INET6, interfaces[i]['ipv6'].split('/')[0]))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--debug', action='store_true')
|
parser.add_argument('--debug', action='store_true')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -69,24 +50,62 @@ if __name__ == '__main__':
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logging.getLogger('zeroconf').setLevel(logging.DEBUG)
|
logging.getLogger('zeroconf').setLevel(logging.DEBUG)
|
||||||
|
|
||||||
infos = []
|
|
||||||
for d in local_domains:
|
|
||||||
d_domain=d.replace('.local','')
|
|
||||||
infos.append(
|
|
||||||
AsyncServiceInfo(
|
|
||||||
type_="_device-info._tcp.local.",
|
|
||||||
name=d_domain+f"._device-info._tcp.local.",
|
|
||||||
addresses=ips,
|
|
||||||
port=80,
|
|
||||||
server=d+'.',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
print("Registration of .local domains, press Ctrl-C to exit...")
|
local_domains = [ d for d in domain_list()['domains'] if d.endswith('.local') ]
|
||||||
aiozc = AsyncZeroconf()
|
|
||||||
loop = asyncio.get_event_loop()
|
m18n.load_namespace("yunohost")
|
||||||
loop.run_until_complete(register_services(infos))
|
m18n.set_locale(get_locale())
|
||||||
print("Registration complete.")
|
|
||||||
|
if settings_get('mdns.interfaces'):
|
||||||
|
wanted_interfaces = settings_get('mdns.interfaces').split()
|
||||||
|
else:
|
||||||
|
wanted_interfaces = []
|
||||||
|
print('No interface listed for broadcast.')
|
||||||
|
|
||||||
|
aiozcs = []
|
||||||
|
interfaces = get_network_interfaces()
|
||||||
|
for interface in wanted_interfaces:
|
||||||
|
infos = []
|
||||||
|
ips = [] # Human-readable IPs
|
||||||
|
b_ips = [] # Binary-convered IPs
|
||||||
|
|
||||||
|
# Parse the IPs and prepare their binary version
|
||||||
|
try:
|
||||||
|
ip = interfaces[interface]['ipv4'].split('/')[0]
|
||||||
|
ips.append(ip)
|
||||||
|
b_ips.append(socket.inet_pton(socket.AF_INET, ip))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
ip = interfaces[interface]['ipv6'].split('/')[0]
|
||||||
|
ips.append(ip)
|
||||||
|
b_ips.append(socket.inet_pton(socket.AF_INET6, ip))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Create a ServiceInfo object for each .local domain
|
||||||
|
for d in local_domains:
|
||||||
|
d_domain=d.replace('.local','')
|
||||||
|
infos.append(
|
||||||
|
AsyncServiceInfo(
|
||||||
|
type_="_device-info._tcp.local.",
|
||||||
|
name=d_domain+f"._device-info._tcp.local.",
|
||||||
|
addresses=b_ips,
|
||||||
|
port=80,
|
||||||
|
server=d+'.',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
print('Adding '+d+' with addresses '+str(ips)+' on interface '+interface)
|
||||||
|
|
||||||
|
# Create an AsyncZeroconf object, store it, and start Service registration
|
||||||
|
aiozc = AsyncZeroconf(interfaces=ips)
|
||||||
|
aiozcs.append(aiozc)
|
||||||
|
print("Registration on interface "+interface+"...")
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.run_until_complete(register_services(aiozc, infos))
|
||||||
|
|
||||||
|
# We are done looping among the interfaces
|
||||||
|
print("Registration complete. Press Ctrl-c to exit...")
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
@ -94,7 +113,8 @@ if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
print("Unregistering...")
|
print("Unregistering...")
|
||||||
loop.run_until_complete(unregister_services(infos))
|
for aiozc in aiozcs:
|
||||||
|
loop.run_until_complete(unregister_services(aiozc, infos))
|
||||||
|
loop.run_until_complete(close_aiozc(aiozc))
|
||||||
print("Unregistration complete.")
|
print("Unregistration complete.")
|
||||||
loop.run_until_complete(close_aiozc(aiozc))
|
|
||||||
|
|
||||||
|
|
|
@ -321,6 +321,7 @@
|
||||||
"global_settings_cant_write_settings": "Could not save settings file, reason: {reason:s}",
|
"global_settings_cant_write_settings": "Could not save settings file, reason: {reason:s}",
|
||||||
"global_settings_key_doesnt_exists": "The key '{settings_key:s}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'",
|
"global_settings_key_doesnt_exists": "The key '{settings_key:s}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'",
|
||||||
"global_settings_reset_success": "Previous settings now backed up to {path:s}",
|
"global_settings_reset_success": "Previous settings now backed up to {path:s}",
|
||||||
|
"global_settings_setting_mdns_interfaces": "Space-separated list of interfaces for mDNS broadcast. Leave empty to disable mDNS.",
|
||||||
"global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server",
|
"global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server",
|
||||||
"global_settings_setting_security_nginx_compatibility": "Compatibility vs. security tradeoff for the web server NGINX. Affects the ciphers (and other security-related aspects)",
|
"global_settings_setting_security_nginx_compatibility": "Compatibility vs. security tradeoff for the web server NGINX. Affects the ciphers (and other security-related aspects)",
|
||||||
"global_settings_setting_security_password_admin_strength": "Admin password strength",
|
"global_settings_setting_security_password_admin_strength": "Admin password strength",
|
||||||
|
|
|
@ -100,6 +100,7 @@ DEFAULTS = OrderedDict(
|
||||||
("smtp.relay.password", {"type": "string", "default": ""}),
|
("smtp.relay.password", {"type": "string", "default": ""}),
|
||||||
("backup.compress_tar_archives", {"type": "bool", "default": False}),
|
("backup.compress_tar_archives", {"type": "bool", "default": False}),
|
||||||
("ssowat.panel_overlay.enabled", {"type": "bool", "default": True}),
|
("ssowat.panel_overlay.enabled", {"type": "bool", "default": True}),
|
||||||
|
("mdns.interfaces", {"type": "string", "default": ""}),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue