package PVE::LXC::Setup::Eisfair; use strict; use warnings; use PVE::LXC; use PVE::Network; use base qw(PVE::LXC::Setup::Base); sub new { my ($class, $conf, $rootdir) = @_; my $self = { conf => $conf, rootdir => $rootdir }; $conf->{ostype} = "eisfair"; return bless $self, $class; } # Eisfair verwendet systemd, daher benötigen wir kein spezielles /dev/lxc-Verzeichnis. sub devttydir { return ''; } sub setup_init { my ($self, $conf) = @_; # Überprüfen, ob systemd verwendet wird my $systemd = $self->ct_readlink('/sbin/init'); if (defined($systemd) && $systemd =~ m@/systemd$@) { $self->setup_container_getty_service($conf); # Vorkonfiguration für systemd-basierte Dienste $self->setup_systemd_preset({ 'NetworkManager.service' => 0, }); } } sub setup_network { my ($self, $conf) = @_; my $base_filename = "/etc/config.d/base"; my $dhcpc_filename = "/etc/config.d/dhcpc"; # Alte Base-Konfigurationsdatei einlesen open(my $base_fh, '<', $base_filename) or die "Kann $base_filename nicht öffnen: $!"; my @base_lines = <$base_fh>; close($base_fh); # Initialisiere Standard-Netzwerk-Konfiguration my $network_settings = { address => '', netmask => '', gateway => $conf->{ip_default_gateway} || '', macaddr => $conf->{hwaddr} || '', network => '', eth_name => 'eth0', dhcp => 0, }; # Netzwerkschnittstellen verarbeiten foreach my $k (keys %$conf) { next if $k !~ m/^net(\d+)$/; # Nur Schnittstellen mit "netX" bearbeiten my $ind = $1; # Netzwerkindex extrahieren my $d = PVE::LXC::Config->parse_lxc_network($conf->{$k}); # DHCP prüfen if ($d->{ip} && $d->{ip} eq 'dhcp') { $network_settings->{dhcp} = 1; $network_settings->{eth_name} = "eth$ind"; next; } # Statische IP und Netzmaske extrahieren if (defined($d->{ip})) { my $ipinfo = PVE::LXC::parse_ipv4_cidr($d->{ip}); $network_settings->{address} = $ipinfo->{address}; $network_settings->{netmask} = $ipinfo->{netmask}; $network_settings->{network} = $self->get_network_address($d->{ip}); } # Gateway und MAC-Adresse $network_settings->{gateway} = $d->{gw} if $d->{gw}; $network_settings->{macaddr} = $d->{hwaddr} || ''; $network_settings->{eth_name} = "eth$ind"; } # Hostname aus der Konfiguration holen my $hostname = $conf->{hostname} || 'eisfair'; # DNS- und Domain-Einstellungen abrufen my ($searchdomain, $nameserver) = $self->lookup_dns_conf($conf); if ($network_settings->{dhcp}) { # DHCP-Konfigurationsdatei bearbeiten open(my $dhcpc_fh, '<', $dhcpc_filename) or die "Kann $dhcpc_filename nicht öffnen: $!"; my @dhcpc_lines = <$dhcpc_fh>; close($dhcpc_fh); foreach my $line (@dhcpc_lines) { if ($line =~ /^START_DHCPC=/) { $line = "START_DHCPC='yes'\n"; } elsif ($line =~ /^DHCP_HOSTNAME=/) { $line = "DHCP_HOSTNAME='$hostname'\n"; } } # DHCP-Konfiguration speichern open($dhcpc_fh, '>', $dhcpc_filename) or die "Kann $dhcpc_filename nicht schreiben: $!"; print $dhcpc_fh @dhcpc_lines; close($dhcpc_fh); # Ausführen des dhcpc.sh-Skripts $self->start_meinscript('dhcpc.sh'); # Dienste starten $self->start_service('resolver'); $self->start_service('dhcpc'); } else { # Statische Netzwerkkonfiguration foreach my $line (@base_lines) { if ($line =~ /^HOSTNAME=/) { $line = "HOSTNAME='$hostname'\n"; } elsif ($line =~ /^IP_ETH_1_IPADDR=/) { $line = "IP_ETH_1_IPADDR='$network_settings->{address}'\n"; } elsif ($line =~ /^IP_ETH_1_NETMASK=/) { $line = "IP_ETH_1_NETMASK='$network_settings->{netmask}'\n"; } elsif ($line =~ /^IP_ETH_1_MACADDR=/) { $line = "IP_ETH_1_MACADDR='$network_settings->{macaddr}'\n"; } elsif ($line =~ /^IP_DEFAULT_GATEWAY=/) { $line = "IP_DEFAULT_GATEWAY='$network_settings->{gateway}'\n"; } elsif ($line =~ /^IP_ETH_1_NAME=/) { $line = "IP_ETH_1_NAME='$network_settings->{eth_name}'\n"; } elsif ($line =~ /^IP_ETH_1_NETWORK=/) { $line = "IP_ETH_1_NETWORK='$network_settings->{network}'\n"; } elsif ($line =~ /^DOMAIN_NAME=/) { $line = "DOMAIN_NAME='$searchdomain'\n"; } elsif ($line =~ /^DNS_SERVER=/) { $line = "DNS_SERVER='$nameserver'\n"; } } # Base-Konfiguration speichern open($base_fh, '>', $base_filename) or die "Kann $base_filename nicht schreiben: $!"; print $base_fh @base_lines; close($base_fh); # DHCP-Konfigurationsdatei bearbeiten open(my $dhcpc_fh, '<', $dhcpc_filename) or die "Kann $dhcpc_filename nicht öffnen: $!"; my @dhcpc_lines = <$dhcpc_fh>; close($dhcpc_fh); foreach my $line (@dhcpc_lines) { if ($line =~ /^START_DHCPC=/) { $line = "START_DHCPC='no'\n"; } } # DHCP-Konfiguration speichern open($dhcpc_fh, '>', $dhcpc_filename) or die "Kann $dhcpc_filename nicht schreiben: $!"; print $dhcpc_fh @dhcpc_lines; close($dhcpc_fh); # Ausführen des dhcpc.sh-Skripts $self->start_meinscript('dhcpc.sh'); # Dienste verwalten $self->stop_service('dhcpc'); $self->restart_service('resolver'); } print "Netzwerk-, Hostname-, Domain- und DNS-Konfiguration für Eisfair wurde aktualisiert.\n"; } # Script ausführen sub start_meinscript { my ($self, $scriptname) = @_; system("/bin/sh /var/install/config.d/$scriptname") == 0 or die "Konnte Script $scriptname nicht starten: $!"; } # Dienstverwaltungsfunktionen bleiben unverändert sub start_service { my ($self, $service) = @_; system("/usr/bin/systemctl start $service") == 0 or die "Konnte Dienst $service nicht starten: $!"; } sub restart_service { my ($self, $service) = @_; system("/usr/bin/systemctl restart $service") == 0 or die "Konnte Dienst $service nicht neu starten: $!"; } sub stop_service { my ($self, $service) = @_; system("/usr/bin/systemctl stop $service") == 0 or die "Konnte Dienst $service nicht stoppen: $!"; } # Funktionalität für Netzwerkadressberechnungen bleibt unverändert sub get_network_address { my ($self, $ip_cidr) = @_; my $ipinfo = PVE::LXC::parse_ipv4_cidr($ip_cidr); my $ip_bin = $self->ip_to_binary($ipinfo->{address}); my $netmask_bin = $self->ip_to_binary($ipinfo->{netmask}); my $network_bin = $self->bitwise_and($ip_bin, $netmask_bin); return $self->binary_to_ip($network_bin); } sub ip_to_binary { my ($self, $ip) = @_; return join('', map { sprintf("%08b", $_) } split(/\./, $ip)); } sub binary_to_ip { my ($self, $binary) = @_; return join('.', map { oct("0b$_") } ($binary =~ /(.{8})/g)); } sub bitwise_and { my ($self, $bin1, $bin2) = @_; return join('', map { substr($bin1, $_, 1) & substr($bin2, $_, 1) } 0 .. length($bin1) - 1); } 1;