50-cloud-init.

This commit is contained in:
devdatt 2025-12-22 23:46:14 +05:30
parent 81b26a05dd
commit ae005d4803
2 changed files with 191 additions and 9 deletions

View File

@ -1,7 +1,8 @@
<?php include 'header.php'; ?>
<?php
// network-form-handler.php
$jsonFile = __DIR__ . '/network.json';
$iface = trim(shell_exec("ip route get 1.1.1.1 | awk '{print $5; exit}'"));
$iface = find_first_physical_ethernet();
$defaults = [
'primary' => [
@ -34,8 +35,6 @@ $defaults = [
'network_secondary_ipv6_dns1' => '',
'network_secondary_ipv6_dns2' => '',
],
'firewall' => 'disable',
'ips' => ['', '', '', '', '']
];
if (file_exists($jsonFile)) {
@ -152,8 +151,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'network_secondary_ipv6_dns1' => $secondary_vlan,
'network_secondary_ipv6_dns2' => $secondary_vlan
],
'firewall' => 'disable',
'ips' => ['', '', '', '', '']
];
$json = json_encode($new, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
if (file_put_contents($jsonFile, $json, LOCK_EX) === false) {
@ -161,14 +158,134 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
$data = $new;
$success = 'Saved.';
$netplan = [
'network' => [
'version' => 2,
'renderer' => 'networkd',
'ethernets' => [
$iface => []
],
'vlans' => []
]
];
/* ---------- helper to build IPv4/IPv6 ---------- */
function build_interface(array $d, string $key): array
{
$cfg = [];
/* IPv4 */
switch ($d['mode']) {
case 'dhcp':
$cfg['dhcp4'] = true;
break;
case 'static':
if (!empty($d["network_{$key}_ip"]) && !empty($d["network_{$key}_subnet"])) {
$cfg['addresses'][] =
$d["network_{$key}_ip"] . '/' . $d["network_{$key}_subnet"];
}
if (!empty($d["network_{$key}_gateway"])) {
$cfg['routes'][] = [
'to' => 'default',
'via' => $d["network_{$key}_gateway"]
];
}
break;
case 'disabled':
$cfg['dhcp4'] = false;
break;
}
update_network();
/* IPv6 */
switch ($d['modev6']) {
case 'auto': // SLAAC
$cfg['accept-ra'] = true;
$cfg['dhcp6'] = false;
break;
case 'dhcp6':
$cfg['dhcp6'] = true;
$cfg['accept-ra'] = false;
break;
case 'static':
if (!empty($d["network_{$key}_ipv6"]) && !empty($d["network_{$key}_ipv6_prefix"])) {
$cfg['addresses'][] =
$d["network_{$key}_ipv6"] . '/' . $d["network_{$key}_ipv6_prefix"];
}
if (!empty($d["network_{$key}_ipv6_gateway"])) {
$cfg['routes'][] = [
'to' => '::/0',
'via' => $d["network_{$key}_ipv6_gateway"]
];
}
$cfg['accept-ra'] = false;
break;
case 'disabled':
$cfg['dhcp6'] = false;
$cfg['accept-ra'] = false;
break;
}
/* DNS */
$dns = array_filter([
$d["network_{$key}_dns1"] ?? '',
$d["network_{$key}_dns2"] ?? '',
$d["network_{$key}_ipv6_dns1"] ?? '',
$d["network_{$key}_ipv6_dns2"] ?? ''
]);
if ($dns) {
$cfg['nameservers']['addresses'] = array_values($dns);
}
return $cfg;
}
/* ---------- VLAN detection ---------- */
$primary_vlan = trim($data['primary']['network_primary_vlan'] ?? '');
$secondary_vlan = trim($data['secondary']['network_secondary_vlan'] ?? '');
$uses_vlan = ($primary_vlan !== '' || $secondary_vlan !== '');
/* ---------- No VLAN: apply primary only ---------- */
if (!$uses_vlan) {
$netplan['network']['ethernets'][$iface] =
build_interface($data['primary'], 'primary');
}
/* ---------- VLAN mode ---------- */ else {
// base iface must exist but empty
$netplan['network']['ethernets'][$iface] = [];
if ($primary_vlan !== '') {
$vif = "{$iface}.{$primary_vlan}";
$netplan['network']['vlans'][$vif] = array_merge([
'id' => (int)$primary_vlan,
'link' => $iface
], build_interface($data['primary'], 'primary'));
}
if ($secondary_vlan !== '') {
$vif = "{$iface}.{$secondary_vlan}";
$netplan['network']['vlans'][$vif] = array_merge([
'id' => (int)$secondary_vlan,
'link' => $iface
], build_interface($data['secondary'], 'secondary'));
}
}
/* ---------- write ---------- */
$yaml = netplan_yaml($netplan);
file_put_contents('/var/www/50-cloud-init.yaml', $yaml);
}
}
}
?>
<?php include 'header.php'; ?>
<form method="POST" novalidate>
<div class="containerindex">
<div class="grid">

View File

@ -40,6 +40,71 @@ function deleteDir(string $dir): void
rmdir($dir);
}
function find_first_physical_ethernet(): ?string
{
foreach (scandir('/sys/class/net') as $iface) {
if ($iface === '.' || $iface === '..' || $iface === 'lo') {
continue;
}
$net = "/sys/class/net/$iface";
if (!is_link("$net/device")) {
continue;
}
$type = @trim(file_get_contents("$net/type"));
if ($type !== '1') {
continue;
}
if (is_dir("$net/wireless")) {
continue;
}
if (is_dir("$net/bridge")) {
continue;
}
$addrAssignType = @trim(file_get_contents("$net/addr_assign_type"));
if ($addrAssignType !== '0') {
continue;
}
return $iface;
}
return null;
}
function netplan_yaml(array $data, int $indent = 0): string
{
$yaml = '';
$pad = str_repeat(' ', $indent);
foreach ($data as $key => $value) {
if (is_array($value)) {
$is_list = array_keys($value) === range(0, count($value) - 1);
if ($is_list) {
foreach ($value as $item) {
if (is_array($item)) {
$yaml .= "{$pad}-\n" . netplan_yaml($item, $indent + 1);
} else {
$yaml .= "{$pad}- {$item}\n";
}
}
} else {
$yaml .= "{$pad}{$key}:\n" . netplan_yaml($value, $indent + 1);
}
} else {
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
}
$yaml .= "{$pad}{$key}: {$value}\n";
}
}
return $yaml;
}
function update_service($which_service)
{