-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
dhcp_server: Add DHCP Options + Enhanced Docs #3643
Conversation
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.
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
WalkthroughWalkthroughThe updates to the Home Assistant DHCP Server add-on mainly focus on improving documentation clarity, updating default configurations, and introducing dynamic scripting for DHCP host management. Key changes include renaming for consistency, revising example configurations, and enhancing the startup script to handle configuration generation dynamically. These changes aim to streamline setup processes and enhance customization flexibility. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Script
participant DHCP Server
Note over User: Configuration Initiation
User->>Script: Define parameters (lease times, domain, DNS, etc.)
Note over Script: Configuration Creation
Script->>Script: Generate DHCP configuration file
Note over Script: Starting Server
Script->>DHCP Server: Start server with generated config
Note over DHCP Server: Operation
DHCP Server-->>User: Serve DHCP requests based on config
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
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.
Actionable comments posted: 0
Outside diff range comments (1)
dhcp_server/data/run.sh (1)
Line range hint
1-1
: Incorrect shebang line for the script.The shebang line
#!/usr/bin/with-contenv bashio
is not recognized. Consider using a standard shebang line for Bash scripts:- #!/usr/bin/with-contenv bashio + #!/bin/bash
Thank you. Signature completed. |
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.
Actionable comments posted: 3
Outside diff range comments (2)
dhcp_server/data/run.sh (1)
Line range hint
1-1
: The shebang line uses an unrecognized format. Consider using a standard shebang for bash scripts.- #!/usr/bin/with-contenv bashio + #!/bin/bashdhcp_server/DOCS.md (1)
Line range hint
20-44
: The configuration section is well-detailed. Consider using a table format for better readability and quicker reference.Tools
LanguageTool
[misspelling] ~14-~14: Possible spelling mistake found. (MORFOLOGIK_RULE_EN_US)
Context: ... Use 1. Set thedomain
option, e.g.,mynetwork.internal
. 2. Save the configuration by...
[style] ~20-~20: Consider removing “of” to be more concise (ALL_OF_THE)
Context: ...suit your needs. This section describes all of the configuration options. Example configu...
# Create DHCP Hosts by enumerating Host List & Keys (IP, MAC, Name, or DHCP Option) | ||
for host in $(bashio::config 'hosts|keys'); do | ||
IP=$(bashio::config "hosts[${host}].ip") | ||
MAC=$(bashio::config "hosts[${host}].mac") | ||
NAME=$(bashio::config "hosts[${host}].name") | ||
|
||
{ | ||
echo "host ${NAME} {" | ||
echo " hardware ethernet ${MAC};" | ||
echo " fixed-address ${IP};" | ||
echo " option host-name \"${NAME}\";" | ||
|
||
# Iterate all Hosts | ||
for key in $(bashio::config "hosts[${host}]|keys"); do | ||
VALUE=$(bashio::config "hosts[${host}].${key}") | ||
|
||
# Validate: Named options | ||
if [[ "${key}" == "ip" ]]; then | ||
echo " fixed-address ${VALUE};" | ||
elif [[ "${key}" == "mac" ]]; then | ||
echo " hardware ethernet ${VALUE};" | ||
|
||
# Validate: Numeric DHCP Option | ||
elif [[ "${key}" =~ ^[0-9]+$ ]]; then | ||
if (( key > 0 && key < 255 )); then | ||
echo " option ${key} ${VALUE};" | ||
fi | ||
fi | ||
done | ||
|
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.
The dynamic host creation logic seems well-implemented, but consider enhancing readability and maintainability by extracting the inner loop into a separate function.
+ function process_host_options() {
+ local host=$1
+ for key in $(bashio::config "hosts[${host}]|keys"); do
+ VALUE=$(bashio::config "hosts[${host}].${key}")
+ if [[ "${key}" == "ip" ]]; then
+ echo " fixed-address ${VALUE};"
+ elif [[ "${key}" == "mac" ]]; then
+ echo " hardware ethernet ${VALUE};"
+ elif [[ "${key}" =~ ^[0-9]+$ ]]; then
+ if (( key > 0 && key < 255 )); then
+ echo " option ${key} ${VALUE};"
+ fi
+ fi
+ done
+ }
- for host in $(bashio::config 'hosts|keys'); do
- NAME=$(bashio::config "hosts[${host}].name")
- {
- echo "host ${NAME} {"
- for key in $(bashio::config "hosts[${host}]|keys"); do
- VALUE=$(bashio::config "hosts[${host}].${key}")
- if [[ "${key}" == "ip" ]]; then
- echo " fixed-address ${VALUE};"
- elif [[ "${key}" == "mac" ]]; then
- echo " hardware ethernet ${VALUE};"
- elif [[ "${key}" =~ ^[0-9]+$ ]]; then
- if (( key > 0 && key < 255 )); then
- echo " option ${key} ${VALUE};"
- fi
- fi
- done
- echo "}"
- } >> "${CONFIG}"
- done
+ for host in $(bashio::config 'hosts|keys'); do
+ NAME=$(bashio::config "hosts[${host}].name")
+ {
+ echo "host ${NAME} {"
+ process_host_options $host
+ echo "}"
+ } >> "${CONFIG}"
+ done
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# Create DHCP Hosts by enumerating Host List & Keys (IP, MAC, Name, or DHCP Option) | |
for host in $(bashio::config 'hosts|keys'); do | |
IP=$(bashio::config "hosts[${host}].ip") | |
MAC=$(bashio::config "hosts[${host}].mac") | |
NAME=$(bashio::config "hosts[${host}].name") | |
{ | |
echo "host ${NAME} {" | |
echo " hardware ethernet ${MAC};" | |
echo " fixed-address ${IP};" | |
echo " option host-name \"${NAME}\";" | |
# Iterate all Hosts | |
for key in $(bashio::config "hosts[${host}]|keys"); do | |
VALUE=$(bashio::config "hosts[${host}].${key}") | |
# Validate: Named options | |
if [[ "${key}" == "ip" ]]; then | |
echo " fixed-address ${VALUE};" | |
elif [[ "${key}" == "mac" ]]; then | |
echo " hardware ethernet ${VALUE};" | |
# Validate: Numeric DHCP Option | |
elif [[ "${key}" =~ ^[0-9]+$ ]]; then | |
if (( key > 0 && key < 255 )); then | |
echo " option ${key} ${VALUE};" | |
fi | |
fi | |
done | |
# Create DHCP Hosts by enumerating Host List & Keys (IP, MAC, Name, or DHCP Option) | |
function process_host_options() { | |
local host=$1 | |
for key in $(bashio::config "hosts[${host}]|keys"); do | |
VALUE=$(bashio::config "hosts[${host}].${key}") | |
if [[ "${key}" == "ip" ]]; then | |
echo " fixed-address ${VALUE};" | |
elif [[ "${key}" == "mac" ]]; then | |
echo " hardware ethernet ${VALUE};" | |
elif [[ "${key}" =~ ^[0-9]+$ ]]; then | |
if (( key > 0 && key < 255 )); then | |
echo " option ${key} ${VALUE};" | |
fi | |
fi | |
done | |
} | |
for host in $(bashio::config 'hosts|keys'); do | |
NAME=$(bashio::config "hosts[${host}].name") | |
{ | |
echo "host ${NAME} {" | |
process_host_options $host | |
echo "}" | |
} >> "${CONFIG}" | |
done |
gateway: 192.168.1.1 | ||
interface: eth0 | ||
broadcast: 192.168.1.255 | ||
``` | ||
|
||
#### Option: `networks.subnet` | ||
|
||
Your network schema/subnet. For example, if your IP addresses are `192.168.1.x` | ||
the subnet becomes `192.168.1.0`. | ||
The first IP of the network. For example, if your IP addresses are `192.168.1.x`, the subnet is `192.168.1.0`. | ||
|
||
#### Option: `networks.netmask` | ||
|
||
Your network netmask. For example, if your IP addresses are `192.168.1.x` the | ||
netmask becomes `255.255.255.0`. | ||
The network netmask. Typically `255.255.255.0` for a class-C network, which includes addresses from `x.x.x.0` to `x.x.x.255` (254 usable addresses). | ||
|
||
A class-B network would have a netmask of `255.255.0.0`, covering addresses from `x.x.0.0` to `x.x.255.255` (65,534 usable addresses). | ||
|
||
If unsure, use `255.255.255.0`. | ||
|
||
#### Option: `networks.range_start` | ||
|
||
Defines the start IP address for the DHCP server to lease IPs for. | ||
Use this together with the `range_end` option to define the range of IP | ||
addresses the DHCP server operates in. | ||
The start IP address for the DHCP lease range. Used with `range_end` to define the range of IP's available for lease by the DHCP server. | ||
|
||
#### Option: `networks.range_end` | ||
|
||
Defines the end IP address for the DHCP server to lease IPs for. | ||
The last IP address for the range of IP addresses available for lease by the DHCP server. | ||
|
||
#### Option: `networks.broadcast` | ||
|
||
The broadcast address specific to the lease range. For example, if your | ||
IP addresses are `192.168.1.x`, the broadcast address is usually `192.168.1.255`. | ||
The broadcast IP address of the network, typically the first three octets of your class-C network plus `.255`, e.g., `192.168.1.255` for `192.168.1.0`. | ||
|
||
#### Option: `networks.gateway` | ||
|
||
Sets the gateway address for that the DHCP server hands out to its clients. | ||
This is usually the IP address of your router. | ||
The router (gateway) address where traffic is routed from your network onto the Internet. | ||
|
||
This is typically the first three octets of your class-C network plus `.1`, e.g., `192.168.1.1` for `192.168.1.0`. | ||
|
||
This is required. If this address is missing or wrong, traffic will not flow onto the Internet. | ||
|
||
#### Option: `networks.interface` | ||
|
||
The network interface to listen to for this network, e.g., `end0`. | ||
The network interface to listen on, e.g., `eth0`, the default for Home Assistant OS. | ||
|
||
### Option: `hosts` (optional) | ||
|
||
This option defines settings for one or host definitions for the DHCP server. | ||
A list of hosts to be assigned fixed IP addresses. Requires the host's MAC address. | ||
|
||
Fixed IP addresses can be anywhere within the network, as long as they are not duplicates. They are not required to be within the `range_start` and `range_end`. This range is for dynamically allocated IP addresses. | ||
|
||
It allows you to fix a host to a specific IP address. | ||
By default, no hosts are configured and none are required for DHCP server function. | ||
|
||
By default, non are configured. | ||
Example: | ||
```yaml | ||
hosts: | ||
- name: MyRouter | ||
mac: aa:bb:cc:dd:ee:ff | ||
ip: 192.168.1.1 | ||
6: 94.140.14.15 # Option 6 w/Family-Friendly DNS Server (AdGuard) | ||
``` | ||
|
||
#### Option: `hosts.name` | ||
|
||
The name of the hostname you'd like to fix an address for. | ||
The name of the host (client) to be assigned a fixed IP address. | ||
|
||
#### Option: `hosts.mac` | ||
|
||
The MAC address of the client device. | ||
The MAC address of the host (client) device. | ||
|
||
#### Option: `hosts.ip` | ||
|
||
The IP address you want the DHCP server to assign. | ||
The IP address assigned to the host (client) device. | ||
|
||
#### Option: Number between 1 - 254 | ||
|
||
For advanced users, you may choose to include numbered DHCP options. | ||
|
||
For example, you may prefer an alternative DNS server for your Router or Children's PC's, that DNS server can be assigned with **Option 6.** | ||
|
||
Assign a custom domain name using **Option 15.** | ||
|
||
Assign a TFTP server for flashing devices using **Option 66.** | ||
|
||
Assign a NetBIOS name server to speed local name resolution on Windows networks using **Option 44.** |
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.
The options descriptions are comprehensive. However, ensure to correct minor typographical errors and improve the clarity of some descriptions to avoid potential user confusion.
- For example, you may prefer an alternative DNS server for your Router or Children's PC's, that DNS server can be assigned with **Option 6.**
+ For example, you may prefer an alternative DNS server for your Router or Children's PCs, that DNS server can be assigned with **Option 6.**
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
The domain name for your network, e.g., `home.internal` or `home.local` (be aware that issues exist with using `.local` for DHCP/DNS) | |
### Option: `dns` (required) | |
The DNS servers your DHCP server gives to your clients. This option can | |
contain a list of servers. By default, it is configured to have Google's | |
public DNS servers: `"8.8.8.8", "8.8.4.4". | |
The DNS (Name Servers) provided to clients. This option can | |
contain a list of servers. By default, Google's public DNS servers are included: `8.8.8.8`, `8.8.4.4`. | |
### Option `ntp` (required) | |
### Option: `ntp` (required) | |
The NTP servers your DHCP server gives to your clients. This option can | |
contain a list of server. By default, none are configured ([]) | |
The NTP servers (Network Time Protocol) provided to clients. By default, no servers are included (`[]`). | |
### Option: `default_lease` (required) | |
The default time in seconds that the IP is leased to your client. | |
Defaults to `86400`, which is one day. | |
The default lease time in seconds. Defaults to `86400` (one day). | |
### Option: `max_lease` (required) | |
The max time in seconds that the IP is leased to your client. | |
Defaults to `172800`, which is two days. | |
The maximum lease time in seconds. Defaults to `172800` (two days). | |
### Option: `networks` (one item required) | |
### Option: `networks` (at least one item required) | |
This option defines settings for one or multiple networks for the DHCP server | |
to hand out IP addresses for. | |
Defines one or more IP address ranges ("networks"). For example, `192.168.1.0` to `192.168.1.255` (also expressed as a Class-C network: `192.168.1.0/24`). | |
At least one network definition in your configuration is required for the | |
DHCP server to work. | |
A minimum of one network is required. Example: | |
```yaml | |
networks: | |
- subnet: 192.168.1.0 | |
netmask: 255.255.255.0 | |
range_start: 192.168.1.100 | |
range_end: 192.168.1.200 | |
gateway: 192.168.1.1 | |
interface: eth0 | |
broadcast: 192.168.1.255 | |
``` | |
#### Option: `networks.subnet` | |
Your network schema/subnet. For example, if your IP addresses are `192.168.1.x` | |
the subnet becomes `192.168.1.0`. | |
The first IP of the network. For example, if your IP addresses are `192.168.1.x`, the subnet is `192.168.1.0`. | |
#### Option: `networks.netmask` | |
Your network netmask. For example, if your IP addresses are `192.168.1.x` the | |
netmask becomes `255.255.255.0`. | |
The network netmask. Typically `255.255.255.0` for a class-C network, which includes addresses from `x.x.x.0` to `x.x.x.255` (254 usable addresses). | |
A class-B network would have a netmask of `255.255.0.0`, covering addresses from `x.x.0.0` to `x.x.255.255` (65,534 usable addresses). | |
If unsure, use `255.255.255.0`. | |
#### Option: `networks.range_start` | |
Defines the start IP address for the DHCP server to lease IPs for. | |
Use this together with the `range_end` option to define the range of IP | |
addresses the DHCP server operates in. | |
The start IP address for the DHCP lease range. Used with `range_end` to define the range of IP's available for lease by the DHCP server. | |
#### Option: `networks.range_end` | |
Defines the end IP address for the DHCP server to lease IPs for. | |
The last IP address for the range of IP addresses available for lease by the DHCP server. | |
#### Option: `networks.broadcast` | |
The broadcast address specific to the lease range. For example, if your | |
IP addresses are `192.168.1.x`, the broadcast address is usually `192.168.1.255`. | |
The broadcast IP address of the network, typically the first three octets of your class-C network plus `.255`, e.g., `192.168.1.255` for `192.168.1.0`. | |
#### Option: `networks.gateway` | |
Sets the gateway address for that the DHCP server hands out to its clients. | |
This is usually the IP address of your router. | |
The router (gateway) address where traffic is routed from your network onto the Internet. | |
This is typically the first three octets of your class-C network plus `.1`, e.g., `192.168.1.1` for `192.168.1.0`. | |
This is required. If this address is missing or wrong, traffic will not flow onto the Internet. | |
#### Option: `networks.interface` | |
The network interface to listen to for this network, e.g., `end0`. | |
The network interface to listen on, e.g., `eth0`, the default for Home Assistant OS. | |
### Option: `hosts` (optional) | |
This option defines settings for one or host definitions for the DHCP server. | |
A list of hosts to be assigned fixed IP addresses. Requires the host's MAC address. | |
Fixed IP addresses can be anywhere within the network, as long as they are not duplicates. They are not required to be within the `range_start` and `range_end`. This range is for dynamically allocated IP addresses. | |
It allows you to fix a host to a specific IP address. | |
By default, no hosts are configured and none are required for DHCP server function. | |
By default, non are configured. | |
Example: | |
```yaml | |
hosts: | |
- name: MyRouter | |
mac: aa:bb:cc:dd:ee:ff | |
ip: 192.168.1.1 | |
6: 94.140.14.15 # Option 6 w/Family-Friendly DNS Server (AdGuard) | |
``` | |
#### Option: `hosts.name` | |
The name of the hostname you'd like to fix an address for. | |
The name of the host (client) to be assigned a fixed IP address. | |
#### Option: `hosts.mac` | |
The MAC address of the client device. | |
The MAC address of the host (client) device. | |
#### Option: `hosts.ip` | |
The IP address you want the DHCP server to assign. | |
The IP address assigned to the host (client) device. | |
#### Option: Number between 1 - 254 | |
For advanced users, you may choose to include numbered DHCP options. | |
For example, you may prefer an alternative DNS server for your Router or Children's PC's, that DNS server can be assigned with **Option 6.** | |
Assign a custom domain name using **Option 15.** | |
Assign a TFTP server for flashing devices using **Option 66.** | |
Assign a NetBIOS name server to speed local name resolution on Windows networks using **Option 44.** | |
For example, you may prefer an alternative DNS server for your Router or Children's PCs, that DNS server can be assigned with **Option 6.** |
Tools
LanguageTool
[misspelling] ~52-~52: Possible spelling mistake found. (MORFOLOGIK_RULE_EN_US)
Context: ...ing.local
for DHCP/DNS) ### Option:dns
(required) The DNS (Name Servers) pro...
[misspelling] ~57-~57: Possible spelling mistake found. (MORFOLOGIK_RULE_EN_US)
Context: ...ded:8.8.8.8
,8.8.4.4
. ### Option:ntp
(required) The NTP servers (Network T...
[misspelling] ~91-~91: Possible spelling mistake found. (MORFOLOGIK_RULE_EN_US)
Context: ...Option:networks.netmask
The network netmask. Typically255.255.255.0
for a class-...
[uncategorized] ~91-~91: A comma may be missing after the conjunctive/linking adverb ‘Typically’. (SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
Context: ...networks.netmaskThe network netmask. Typically
255.255.255.0` for a class-C network, ...
[misspelling] ~93-~93: Possible spelling mistake found. (MORFOLOGIK_RULE_EN_US)
Context: ...esses). A class-B network would have a netmask of255.255.0.0
, covering addresses fr...
[non-conformance] ~99-~99: Please check whether ‘and’ might be the correct word here instead of ‘end’. (CONFUSION_RULE_END_AND)
Context: ...ess for the DHCP lease range. Used withrange_end
to define the range of IP's available ...
[non-conformance] ~125-~125: Please check whether ‘and’ might be the correct word here instead of ‘end’. (CONFUSION_RULE_END_AND)
Context: ...ired to be within therange_start
andrange_end
. This range is for dynamically allocat...
[typographical] ~150-~150: If you want to indicate numerical ranges or time ranges, consider using an en dash. (DASH_RULE)
Context: ...) device. #### Option: Number between 1 - 254 For advanced users, you may choose ...
[formatting] ~154-~154: A possessive apostrophe is not correct here. Did you mean “PCs” (as in ‘more than one PC’)? (ABBREVIATION_APOSTROPHE_S)
Context: ...NS server for your Router or Children's PC's, that DNS server can be assigned with *...
Markdownlint
74-74: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines
130-130: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines
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.
Thanks for your contribution!
You also need to bump the add-on version in config.yaml
and add an entry to the CHANGELOG.md file.
@@ -1,34 +1,34 @@ | |||
# Home Assistant Add-on: DHCP server | |||
# Home Assistant Add-on: DHCP Server |
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.
We generally use sentence style capitalization, also for titles, as per Microsoft writing style guideline.
@@ -38,99 +38,126 @@ networks: | |||
range_end: 192.168.1.200 | |||
broadcast: 192.168.1.255 | |||
gateway: 192.168.1.1 | |||
interface: end0 | |||
interface: eth0 |
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.
Almost none of the OS installations by default use eth0
these days. Someone even recently asked to change that #3638 😅
So let's leave it as end0
now.
The IP address you want the DHCP server to assign. | ||
The IP address assigned to the host (client) device. | ||
|
||
#### Option: Number between 1 - 254 |
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.
I don't think the Supervisor/Frontend allows to set these keys in the add-on config without adding them to the schema in config.yaml no?
What we could do here as a work around is add a config option extra_dhcp_options
which is a list of itmes with a key
and value
property.
DHCP Options + Enhanced Docs
Context and Rationale
The
addon_core_dhcp_server
utilizes the standard ISC DHCP server which supports the full DHCP standard.The current Home Assistant YAML only accepts three named parameters per host (ip, mac, name).
This limits the ability to specify other DHCP options such as Option 66 (TFTP Server), which is essential for scenarios like network booting or flashing firmware to bricked devices.
DHCP Options have a variety of home usage, including specifying alternate domains or name servers for certain hosts.
Because this feature is already implemented, it's simply a matter of adding validation to the YAML enumerator that translates to the
dhcpd.conf
.In addition to the enhancement, I've thoroughly edited the documentation for the add-on.
Proposed Changes
YAML Parsing:
Documentation
Benefits
Enhanced Flexibility: Users can define any standard DHCP options, increasing the flexibility and capability of the DHCP server.
User Empowerment: Advanced users can leverage the full feature set of the ISC DHCP server without waiting for specific parameters to be implemented in Home Assistant.
Example YAML Structure:
Summary by CodeRabbit
Documentation
New Features
Refactor
run.sh
script to dynamically create DHCP hosts and handle various DHCP options based on key types.