-
Notifications
You must be signed in to change notification settings - Fork 3.9k
alfred: add new package #30161
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
alfred: add new package #30161
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| config ALFRED_NEEDS_lua | ||
| bool | ||
|
|
||
| config ALFRED_NEEDS_libgps | ||
| bool | ||
|
|
||
| config PACKAGE_ALFRED_VIS | ||
| bool "enable vis server for alfred" | ||
| depends on PACKAGE_alfred | ||
| default y | ||
|
|
||
| config PACKAGE_ALFRED_BATHOSTS | ||
| bool "enable autogeneration of /etc/bat-hosts" | ||
| depends on PACKAGE_alfred | ||
| select ALFRED_NEEDS_lua | ||
| default n | ||
|
|
||
| config PACKAGE_ALFRED_GPSD | ||
| bool "enable gpsd service for alfred" | ||
| depends on PACKAGE_alfred | ||
| select ALFRED_NEEDS_libgps | ||
| default n |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # SPDX-License-Identifier: GPL-2.0-only | ||
|
|
||
| include $(TOPDIR)/rules.mk | ||
|
|
||
| PKG_NAME:=alfred | ||
| PKG_VERSION:=2026.2 | ||
| PKG_RELEASE:=1 | ||
|
|
||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | ||
| PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) | ||
| PKG_HASH:=d995748be5f62a42091525ccc102df5ac642186e9b9014698a955a4469b69b96 | ||
|
|
||
| PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de> | ||
| PKG_LICENSE:=GPL-2.0-only MIT | ||
| PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT | ||
|
|
||
| PKG_BUILD_PARALLEL:=1 | ||
| PKG_BUILD_FLAGS:=gc-sections lto | ||
|
|
||
| PKG_CONFIG_DEPENDS += \ | ||
| CONFIG_ALFRED_NEEDS_lua \ | ||
| CONFIG_ALFRED_NEEDS_libgps \ | ||
| CONFIG_PACKAGE_ALFRED_VIS \ | ||
| CONFIG_PACKAGE_ALFRED_BATHOSTS \ | ||
| CONFIG_PACKAGE_ALFRED_GPSD | ||
|
|
||
| include $(INCLUDE_DIR)/package.mk | ||
|
|
||
| define Package/alfred | ||
| SECTION:=net | ||
| CATEGORY:=Network | ||
| SUBMENU:=Wireless | ||
| TITLE:=A.L.F.R.E.D. - Almighty Lightweight Fact Remote Exchange Daemon | ||
| URL:=https://www.open-mesh.org/ | ||
| DEPENDS:=@IPV6 +libnl-tiny +librt \ | ||
| +ALFRED_NEEDS_lua:lua \ | ||
| +ALFRED_NEEDS_libgps:libgps | ||
| endef | ||
|
|
||
| define Package/alfred/description | ||
| alfred is a user space daemon for distributing arbitrary local information | ||
| over the mesh/network in a decentralized fashion. This data can be anything | ||
| which appears to be useful - originally designed to replace the batman-adv | ||
| visualization (vis), you may distribute hostnames, phone books, administration | ||
| information, DNS information, the local weather forecast ... | ||
|
|
||
| alfred runs as daemon in the background of the system. A user may insert | ||
| information by using the alfred binary on the command line, or use special | ||
| programs to communicate with alfred (done via unix sockets). alfred then takes | ||
| care of distributing the local information to other alfred servers on other | ||
| nodes. This is done via IPv6 link-local multicast, and does not require any | ||
| configuration. A user can request data from alfred, and will receive the | ||
| information available from all alfred servers in the network. | ||
| endef | ||
|
|
||
| define Package/alfred/conffiles | ||
| /etc/config/alfred | ||
| /etc/alfred/bat-hosts.lua | ||
| endef | ||
|
|
||
| define Package/alfred/config | ||
| source "$(SOURCE)/Config.in" | ||
| endef | ||
|
|
||
| MAKE_FLAGS += \ | ||
| CONFIG_ALFRED_VIS=$(if $(CONFIG_PACKAGE_ALFRED_VIS),y,n) \ | ||
| CONFIG_ALFRED_GPSD=$(if $(CONFIG_PACKAGE_ALFRED_GPSD),y,n) \ | ||
| CONFIG_ALFRED_CAPABILITIES=n \ | ||
| LIBNL_NAME="libnl-tiny" \ | ||
| LIBNL_GENL_NAME="libnl-tiny" \ | ||
| REVISION="$(PKG_VERSION)-openwrt-$(PKG_RELEASE)" | ||
|
|
||
| define Package/alfred/install | ||
| $(INSTALL_DIR) $(1)/usr/sbin | ||
| $(INSTALL_BIN) $(PKG_BUILD_DIR)/alfred $(1)/usr/sbin/ | ||
| $(if $(CONFIG_PACKAGE_ALFRED_VIS), \ | ||
| $(INSTALL_BIN) $(PKG_BUILD_DIR)/vis/batadv-vis $(1)/usr/sbin/) | ||
| $(if $(CONFIG_PACKAGE_ALFRED_GPSD), \ | ||
| $(INSTALL_BIN) $(PKG_BUILD_DIR)/gpsd/alfred-gpsd $(1)/usr/sbin/) | ||
| $(INSTALL_DIR) $(1)/etc/init.d | ||
| $(INSTALL_BIN) ./files/alfred.init $(1)/etc/init.d/alfred | ||
| $(INSTALL_DIR) $(1)/etc/config | ||
| $(INSTALL_CONF) ./files/alfred.config $(1)/etc/config/alfred | ||
| $(INSTALL_DIR) $(1)/etc/alfred | ||
| $(if $(CONFIG_PACKAGE_ALFRED_BATHOSTS), \ | ||
| $(INSTALL_BIN) ./files/bat-hosts.lua $(1)/etc/alfred/bat-hosts.lua) | ||
| endef | ||
|
|
||
| $(eval $(call BuildPackage,alfred)) | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||
| config 'alfred' 'alfred' | ||||||||||
| list interface 'br-lan' | ||||||||||
| option mode 'master' | ||||||||||
| option batmanif 'bat0' | ||||||||||
| option start_vis '1' | ||||||||||
| option run_facters '1' | ||||||||||
| # REMOVE THIS LINE TO ENABLE ALFRED | ||||||||||
| option disabled '1' | ||||||||||
|
Comment on lines
+7
to
+8
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: "THIS LINE" reads as the comment itself, but deleting the comment does nothing — it's the
Suggested change
Generated by Claude Code |
||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,97 @@ | ||||||
| #!/bin/sh /etc/rc.common | ||||||
|
|
||||||
| # | ||||||
| # This is free software, licensed under the GNU General Public License v2. | ||||||
| # See /LICENSE for more information. | ||||||
| # | ||||||
|
|
||||||
| START=99 | ||||||
| USE_PROCD=1 | ||||||
| alfred_args="" | ||||||
| vis_args="" | ||||||
| facters_dir="/etc/alfred" | ||||||
| enable=0 | ||||||
| vis_enable=0 | ||||||
|
|
||||||
| append_interface() | ||||||
| { | ||||||
| append "interfaces" "$1" "," | ||||||
| } | ||||||
|
|
||||||
| alfred_start() { | ||||||
| local args="" | ||||||
| local section="$1" | ||||||
| local disabled interface mode | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
Generated by Claude Code |
||||||
| local interfaces | ||||||
|
|
||||||
| # check if section is disabled | ||||||
| config_get_bool disabled "$section" disabled 0 | ||||||
| [ $disabled = 0 ] || return 1 | ||||||
|
|
||||||
| args="-f" | ||||||
|
|
||||||
| config_list_foreach "$section" "interface" append_interface | ||||||
| if [ -z "$interfaces" ]; then | ||||||
| config_get interface "$section" interface | ||||||
| append_interface "$interface" | ||||||
| fi | ||||||
| append args "-i $interfaces" | ||||||
|
|
||||||
| config_get mode "$section" mode | ||||||
| [ "$mode" = "master" ] && append args "-m" | ||||||
|
|
||||||
| config_get batmanif "$section" batmanif | ||||||
| append args "-b $batmanif" | ||||||
|
|
||||||
| append alfred_args "$args" | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is a single section the only supported configuration? If so, opening one procd instance per section inside Generated by Claude Code |
||||||
| enable=1 | ||||||
|
|
||||||
| config_get_bool start_vis "$section" start_vis 0 | ||||||
| if [ "$start_vis" = 1 ] && [ -x /usr/sbin/batadv-vis ]; then | ||||||
| vis_enable=1 | ||||||
| append vis_args "-i $batmanif -s" | ||||||
| fi | ||||||
|
|
||||||
| config_get_bool run_facters "$section" run_facters 0 | ||||||
|
|
||||||
| return 0 | ||||||
| } | ||||||
|
|
||||||
| start_service() { | ||||||
| config_load "alfred" | ||||||
| config_foreach alfred_start alfred | ||||||
|
|
||||||
| [ "$enable" = "0" ] && return 0 | ||||||
|
|
||||||
| procd_open_instance "alfred" | ||||||
| procd_set_param command /usr/sbin/alfred | ||||||
| procd_append_param command ${alfred_args} | ||||||
| procd_close_instance | ||||||
|
|
||||||
| [ "$vis_enable" = "1" ] && { | ||||||
| procd_open_instance "batadv-vis" | ||||||
| procd_set_param command /usr/sbin/batadv-vis | ||||||
| procd_append_param command ${vis_args} | ||||||
| procd_close_instance | ||||||
| } | ||||||
|
|
||||||
| [ "$run_facters" = "1" ] && { | ||||||
| ( for file in $facters_dir/* ; do [ -x $file ] && $file ; done ) | ||||||
| if ! ( grep -q "for file in $facters_dir/\* ; do " /etc/crontabs/root 2>/dev/null ) ; then | ||||||
| echo "*/5 * * * * ( for file in $facters_dir/* ; do [ -x \$file ] && \$file ; done )" >> /etc/crontabs/root | ||||||
| /etc/init.d/cron enable | ||||||
| /etc/init.d/cron restart | ||||||
| fi | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| service_triggers() { | ||||||
| procd_add_reload_trigger "alfred" | ||||||
| } | ||||||
|
|
||||||
| stop_service() { | ||||||
| [ -e /etc/crontabs/root ] && { | ||||||
| sed "\|for file in $facters_dir/\* ; do |d" -i /etc/crontabs/root | ||||||
| /etc/init.d/cron restart | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,116 @@ | ||||||||||||||||||||||||||||
| #!/usr/bin/lua | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local type_id = 64 -- bat-hosts | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| function get_hostname() | ||||||||||||||||||||||||||||
| local hostfile = io.open("/proc/sys/kernel/hostname", "r") | ||||||||||||||||||||||||||||
| if not hostfile then return nil end | ||||||||||||||||||||||||||||
| local ret_string = hostfile:read() | ||||||||||||||||||||||||||||
| hostfile:close() | ||||||||||||||||||||||||||||
| return ret_string | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| function get_interfaces_names() | ||||||||||||||||||||||||||||
| local ret = {} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for name in io.popen("ls -1 /sys/class/net/"):lines() do | ||||||||||||||||||||||||||||
| table.insert(ret, name) | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return ret | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| function get_interface_address(name) | ||||||||||||||||||||||||||||
| -- /sys/class/net also contains plain files, e.g. bonding_masters | ||||||||||||||||||||||||||||
| -- once the bonding module is loaded, which have no address below them | ||||||||||||||||||||||||||||
| local addressfile = io.open("/sys/class/net/"..name.."/address", "r") | ||||||||||||||||||||||||||||
| if not addressfile then return nil end | ||||||||||||||||||||||||||||
| local ret_string = addressfile:read() | ||||||||||||||||||||||||||||
| addressfile:close() | ||||||||||||||||||||||||||||
| return ret_string | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+31
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Returning
Generated by Claude Code |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local function generate_bat_hosts() | ||||||||||||||||||||||||||||
| -- get hostname and interface macs/names | ||||||||||||||||||||||||||||
| -- then return a table containing valid bat-hosts lines | ||||||||||||||||||||||||||||
| local n, i | ||||||||||||||||||||||||||||
| local ifaces, ret = {}, {} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local hostname = get_hostname() | ||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Same applies when the file opens but is empty —
Suggested change
Bailing out with the empty Generated by Claude Code |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for n, i in ipairs(get_interfaces_names()) do | ||||||||||||||||||||||||||||
| local address = get_interface_address(i) | ||||||||||||||||||||||||||||
| if address and not ifaces[address] then ifaces[address] = i end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for mac, iname in pairs(ifaces) do | ||||||||||||||||||||||||||||
| if mac:match("^%x%x:%x%x:%x%x:%x%x:%x%x:%x%x$") and not mac:match("00:00:00:00:00:00") then | ||||||||||||||||||||||||||||
| table.insert(ret, mac.." "..hostname.."_"..iname.."\n") | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return ret | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local function publish_bat_hosts() | ||||||||||||||||||||||||||||
| -- pass a raw chunk of data to alfred | ||||||||||||||||||||||||||||
| local fd = io.popen("alfred -s " .. type_id, "w") | ||||||||||||||||||||||||||||
| if fd then | ||||||||||||||||||||||||||||
| local ret = generate_bat_hosts() | ||||||||||||||||||||||||||||
| if ret then | ||||||||||||||||||||||||||||
| fd:write(table.concat(ret)) | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| fd:close() | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local function write_bat_hosts(rows) | ||||||||||||||||||||||||||||
| local content = { "### /tmp/bat-hosts generated by alfred-bat-hosts\n", | ||||||||||||||||||||||||||||
| "### /!\\ This file is overwritten every 5 minutes /!\\\n", | ||||||||||||||||||||||||||||
| "### (To keep manual changes, replace /etc/bat-hosts symlink with a static file)\n" } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| -- merge the chunks from all nodes, de-escaping newlines | ||||||||||||||||||||||||||||
| for _, row in ipairs(rows) do | ||||||||||||||||||||||||||||
| local node, value = unpack(row) | ||||||||||||||||||||||||||||
| table.insert(content, "# Node ".. node .. "\n") | ||||||||||||||||||||||||||||
| table.insert(content, value:gsub("\x0a", "\n") .. "\n") | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| -- write parsed content down to disk | ||||||||||||||||||||||||||||
| local fd = io.open("/tmp/bat-hosts", "w") | ||||||||||||||||||||||||||||
| if fd then | ||||||||||||||||||||||||||||
| fd:write(table.concat(content)) | ||||||||||||||||||||||||||||
| fd:close() | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| -- try to make a symlink in /etc pointing to /tmp, | ||||||||||||||||||||||||||||
| -- if it exists, ln will do nothing. | ||||||||||||||||||||||||||||
| os.execute("ln -ns /tmp/bat-hosts /etc/bat-hosts 2>/dev/null") | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| local function receive_bat_hosts() | ||||||||||||||||||||||||||||
| -- read raw chunks from alfred, convert them to a nested table and call write_bat_hosts | ||||||||||||||||||||||||||||
| -- "alfred -r" can fail in slave nodes (returns empty stdout), so: | ||||||||||||||||||||||||||||
| -- check output is not null before writing /tmp/bat-hosts, and retry 3 times before giving up. | ||||||||||||||||||||||||||||
| for n = 1, 3 do | ||||||||||||||||||||||||||||
| local fd = io.popen("alfred -r " .. type_id) | ||||||||||||||||||||||||||||
| --[[ this command returns something like | ||||||||||||||||||||||||||||
| { "54:e6:fc:b9:cb:37", "00:11:22:33:44:55 ham_wlan0\x0a00:22:33:22:33:22 ham_eth0\x0a" }, | ||||||||||||||||||||||||||||
| { "90:f6:52:bb:ec:57", "00:22:33:22:33:23 spam\x0a" }, | ||||||||||||||||||||||||||||
| ]]-- | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if fd then | ||||||||||||||||||||||||||||
| local output = fd:read("*a") | ||||||||||||||||||||||||||||
| fd:close() | ||||||||||||||||||||||||||||
| if output and output ~= "" then | ||||||||||||||||||||||||||||
| assert(loadstring("rows = {" .. output .. "}"))() | ||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
alfred's client does escape quotes/backslashes/non-printables as Is relying on alfred's escaping here deliberate? Generated by Claude Code |
||||||||||||||||||||||||||||
| write_bat_hosts(rows) | ||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| publish_bat_hosts() | ||||||||||||||||||||||||||||
| receive_bat_hosts() | ||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this entry is unconditional, but the file is only installed when
CONFIG_PACKAGE_ALFRED_BATHOSTSis set (lines 84-85), and it goes in via$(INSTALL_BIN)as an executable facter script rather than as a config file.Nothing breaks — the packaging step skips conffiles that aren't in the image (
package-pack.mk:[ -f $(IDIR)/$file ] || continue) — so this is only worth confirming the entry is intentional rather than a leftover.Generated by Claude Code