Skip to content

Commit

Permalink
Check host network connectivity
Browse files Browse the repository at this point in the history
Check host network connectivity and offer DNS alternatives in case host
internet is not available. This allows users with broken DNS setup
to configure the host network with a working DNS.

Requires home-assistant/supervisor#5321.
  • Loading branch information
agners committed Oct 3, 2024
1 parent 5109754 commit bb84def
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 5 deletions.
28 changes: 27 additions & 1 deletion rootfs/usr/share/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h2>This may take 20 minutes or more</h2>
</div>
</div>
</div>
<div class="state-error">
<div id="state-error" class="error">
<h1>Error installing Home Assistant</h1>
<div role="alert" class="alert">
<svg class="alert-icon" preserveAspectRatio="xMidYMid meet" focusable="false" role="img" aria-hidden="true"
Expand All @@ -42,6 +42,32 @@ <h1>Error installing Home Assistant</h1>
</div>
</div>
</div>
<div id="state-network-issue" class="warning">
<h1>Networking issue detected</h1>
<div role="alert" class="alert warning">
<svg class="alert-icon" preserveAspectRatio="xMidYMid meet" focusable="false" role="img" aria-hidden="true"
viewBox="0 0 24 24">
<g>
<path
d="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z">
</path>
</g>
</svg>
<div class="alert-content">
<p>
There is a network issue on the host operating system, which prevents Home Assistant from installing completely.
This might be DNS related, currently using <span id="current_dns"></span> as DNS.
</p>
<p>
Update your routers configuration if you want to use a custom DNS. Alternatively, you can try a public DNS.
</p>
</div>
</div>
<div class="actions">
<button id="try_cloudflare_dns" class="button">Try Cloudflare DNS</button>
<button id="try_google_dns" class="button">Try Google DNS</button>
</div>
</div>
<pre id="log"></pre>
<button id="show_logs">Show details</button>
</div>
Expand Down
100 changes: 99 additions & 1 deletion rootfs/usr/share/www/static/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function fetchLogs() {
res.text().then(function (text) {
var logElement = document.getElementById("log");
if (errorCheck.test(text)) {
document.body.classList.add("error");
document.body.classList.add("supervisor-error");
document.getElementById("show_logs").innerText = "Download raw logs";
logElement.showFull = true;
}
Expand Down Expand Up @@ -109,8 +109,40 @@ function scheduleFetchLogs() {
scheduleTimeout = setTimeout(fetchLogs, 5000);
}

function fetchNetworkInfo() {
fetch("/supervisor/network/info").then(function (res) {
if (!res.ok)
return;

res.json().then(function (data) {
if (!data.data.host_internet) {
document.body.classList.add("network-issue");
}

if (document.body.classList.contains("network-issue")) {
const primaryInterface = data.data.interfaces.find(intf => intf.primary);
var dnsElement = document.getElementById("current_dns");
if (!primaryInterface) {
dnsElement.innerText = "(no primary interface)";
} else {
dnsElement.innerText = [...(primaryInterface.ipv4?.nameservers || []), ...(primaryInterface.ipv6?.nameservers || [])].join(', ');
}
}

});
}, scheduleFetchNetworkInfo());
}

var scheduleNetworkTimeout;

function scheduleFetchNetworkInfo() {
clearTimeout(scheduleNetworkTimeout);
scheduleNetworkTimeout = setTimeout(fetchNetworkInfo, 5000);
}

scheduleTry();
fetchLogs();
fetchNetworkInfo();

document.getElementById("show_logs").addEventListener("click", toggleLogs);
function toggleLogs(event) {
Expand All @@ -136,6 +168,72 @@ function toggleLogs(event) {
}
}

document.getElementById("try_cloudflare_dns").addEventListener("click", function() {
setDns(["1.1.1.1", "1.0.0.1"], ["2606:4700:4700::1111", "2606:4700:4700::1001"]);
});

document.getElementById("try_google_dns").addEventListener("click", function() {
setDns(["8.8.8.8", "8.8.4.4"], ["2001:4860:4860::8888", "2001:4860:4860::8844"]);
});

function setDns(ipv4nameservers, ipv6nameservers) {
// Step 1: Fetch the primary network interface from the /network/info endpoint
fetch("/supervisor/network/info", {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch network info');
}
return response.json();
})
.then(data => {
// Step 2: Find the primary interface
const primaryInterface = data.data.interfaces.find(intf => intf.primary && intf.enabled);
if (!primaryInterface) {
throw new Error('No primary interface found');
}

// Step 3: Update the DNS settings for the primary interface
const payload = {
ipv4: {
method: "auto",
nameservers: ipv4nameservers
},
ipv6: {
method: "auto",
nameservers: ipv6nameservers
}
};

return fetch(`/supervisor/network/interface/${primaryInterface.interface}/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload)
});
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to update the interface');
}
fetchNetworkInfo();
return response.json();
})
.then(data => {
console.log('Success:', data);
// Optionally handle the success case, e.g., updating the UI or showing a message
})
.catch((error) => {
console.error('Error:', error);
// Optionally handle the error case, e.g., showing an error message
});
}

var dialogs = document.querySelectorAll('dialog');
dialogs.forEach(dialog => {
dialogPolyfill.registerDialog(dialog);
Expand Down
34 changes: 31 additions & 3 deletions rootfs/usr/share/www/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ body {
white-space: nowrap;
}

.error .state-normal {
.supervisor-error .state-normal {
display: none;
}

.state-error {
#state-error {
display: none;
}

.error .state-error {
.supervisor-error #state-error {
display: block;
}

Expand All @@ -60,6 +60,9 @@ body {
pointer-events: none;
content: "";
border-radius: 4px;
}

.error .alert::after {
background-color: #db4437;
}

Expand All @@ -76,6 +79,31 @@ body {
margin-right: 0;
}

#state-network-issue {
display: none;
}

.network-issue #state-network-issue {
display: block;
}

.network-issue .state-normal {
display: none;
}

.warning .alert-icon {
fill: #ffa600;
}

.warning .alert::after {
background-color: #ffa600;
}

.warning .actions {
display: flex;
margin-bottom: 16px;
}

.header {
text-align: center;
margin-top: 32px;
Expand Down

0 comments on commit bb84def

Please sign in to comment.